changeset 12:7c56bb8ffc4b jdk6-b11

Import b11
author Mark Wielaard <mark@klomp.org>
date Thu, 10 Jul 2008 00:00:00 +0200
parents 62ada42e1d42
children 0ae5c8374b98
files THIRD_PARTY_README control/make/make/sanity-rules.gmk corba/make/com/sun/corba/se/sources/Makefile corba/make/sun/rmi/corbalogsources/Makefile corba/make/tools/Makefile corba/make/tools/logutil/Makefile corba/src/share/classes/com/sun/tools/corba/se/idl/first.set corba/src/share/classes/com/sun/tools/corba/se/idl/follow.set corba/src/share/classes/com/sun/tools/corba/se/idl/grammar.idl corba/src/share/classes/com/sun/tools/corba/se/idl/grammar3.idl corba/src/share/classes/com/sun/tools/corba/se/idl/idl.prp corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp corba/src/share/classes/com/sun/tools/corba/se/logutil/IndentingPrintWriter.java corba/src/share/classes/com/sun/tools/corba/se/logutil/Input.java corba/src/share/classes/com/sun/tools/corba/se/logutil/InputCode.java corba/src/share/classes/com/sun/tools/corba/se/logutil/InputException.java corba/src/share/classes/com/sun/tools/corba/se/logutil/MC.java corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jscheme.jar corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jschemelogutil.jar corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc.scm corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/run hotspot/agent/kk/src/share/lib/jlfgr-1_0.jar hotspot/agent/kk/src/share/lib/maf-1_0.jar hotspot/build/linux/Queens.class hotspot/build/linux/makefiles/buildtree.make hotspot/build/solaris/Queens.class hotspot/build/solaris/makefiles/buildtree.make hotspot/src/os/linux/vm/jvm_linux.cpp hotspot/src/os/linux/vm/os_linux.cpp hotspot/src/os/linux/vm/os_linux.hpp hotspot/src/os/linux/vm/vmError_linux.cpp hotspot/src/os/solaris/vm/vmError_solaris.cpp hotspot/src/share/vm/adlc/archDesc.cpp hotspot/src/share/vm/adlc/archDesc.hpp hotspot/src/share/vm/adlc/main.cpp hotspot/src/share/vm/classfile/dictionary.cpp hotspot/src/share/vm/gc_implementation/parNew/vmStructs_parNew.hpp hotspot/src/share/vm/includeDB_core hotspot/src/share/vm/interpreter/oopMapCache.cpp hotspot/src/share/vm/memory/compactingPermGenGen.cpp hotspot/src/share/vm/oops/instanceKlass.cpp hotspot/src/share/vm/oops/instanceKlass.hpp hotspot/src/share/vm/oops/markOop.cpp hotspot/src/share/vm/oops/markOop.hpp hotspot/src/share/vm/oops/methodOop.cpp hotspot/src/share/vm/oops/methodOop.hpp hotspot/src/share/vm/opto/cfgnode.cpp hotspot/src/share/vm/opto/loopopts.cpp hotspot/src/share/vm/opto/memnode.cpp hotspot/src/share/vm/opto/parse3.cpp hotspot/src/share/vm/prims/jvmti.xml hotspot/src/share/vm/prims/jvmti.xsl hotspot/src/share/vm/prims/jvmtiLib.xsl hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp hotspot/src/share/vm/utilities/copy.cpp hotspot/test/compiler/6659207/Test.java jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java jaxp/src/share/classes/com/sun/org/apache/xml/internal/utils/ThreadControllerWrapper.java jaxp/src/share/classes/com/sun/xml/internal/stream/events/XMLEventAllocatorImpl.java jaxws/src/share/classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java jdk/make/THIRD_PARTY_README jdk/make/common/shared/Defs-utils.gmk jdk/make/common/shared/Platform.gmk jdk/make/common/shared/Sanity.gmk jdk/make/java/java/Makefile jdk/make/java/nio/Makefile jdk/make/tools/Makefile jdk/make/tools/auto_multi/Makefile jdk/make/tools/src/build/tools/automulti/AutoMulti.java jdk/make/tools/src/build/tools/automulti/README.txt jdk/make/tools/src/build/tools/automulti/TestALFGenerator.java jdk/make/tools/src/build/tools/automulti/TestALFLookAndFeel.java jdk/make/tools/winver/Makefile jdk/make/tools/winver/bin/winver.exe jdk/make/tools/winver/src/StdAfx.cpp jdk/make/tools/winver/src/StdAfx.h jdk/make/tools/winver/src/winver.cpp jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java jdk/src/share/classes/com/sun/media/sound/DLSInfo.java jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java jdk/src/share/classes/com/sun/media/sound/DLSModulator.java jdk/src/share/classes/com/sun/media/sound/DLSRegion.java jdk/src/share/classes/com/sun/media/sound/DLSSample.java jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java jdk/src/share/classes/com/sun/media/sound/FFT.java jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java jdk/src/share/classes/com/sun/media/sound/ModelConnectionBlock.java jdk/src/share/classes/com/sun/media/sound/ModelDestination.java jdk/src/share/classes/com/sun/media/sound/ModelDirectedPlayer.java jdk/src/share/classes/com/sun/media/sound/ModelDirector.java jdk/src/share/classes/com/sun/media/sound/ModelIdentifier.java jdk/src/share/classes/com/sun/media/sound/ModelInstrument.java jdk/src/share/classes/com/sun/media/sound/ModelInstrumentComparator.java jdk/src/share/classes/com/sun/media/sound/ModelMappedInstrument.java jdk/src/share/classes/com/sun/media/sound/ModelOscillator.java jdk/src/share/classes/com/sun/media/sound/ModelOscillatorStream.java jdk/src/share/classes/com/sun/media/sound/ModelPatch.java jdk/src/share/classes/com/sun/media/sound/ModelPerformer.java jdk/src/share/classes/com/sun/media/sound/ModelSource.java jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java jdk/src/share/classes/com/sun/media/sound/ModelStandardTransform.java jdk/src/share/classes/com/sun/media/sound/ModelTransform.java jdk/src/share/classes/com/sun/media/sound/ModelWavetable.java jdk/src/share/classes/com/sun/media/sound/RIFFInvalidDataException.java jdk/src/share/classes/com/sun/media/sound/RIFFInvalidFormatException.java jdk/src/share/classes/com/sun/media/sound/RIFFReader.java jdk/src/share/classes/com/sun/media/sound/RIFFWriter.java jdk/src/share/classes/com/sun/media/sound/SF2GlobalRegion.java jdk/src/share/classes/com/sun/media/sound/SF2Instrument.java jdk/src/share/classes/com/sun/media/sound/SF2InstrumentRegion.java jdk/src/share/classes/com/sun/media/sound/SF2Layer.java jdk/src/share/classes/com/sun/media/sound/SF2LayerRegion.java jdk/src/share/classes/com/sun/media/sound/SF2Modulator.java jdk/src/share/classes/com/sun/media/sound/SF2Region.java jdk/src/share/classes/com/sun/media/sound/SF2Sample.java jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java jdk/src/share/classes/com/sun/media/sound/SF2SoundbankReader.java jdk/src/share/classes/com/sun/media/sound/SimpleInstrument.java jdk/src/share/classes/com/sun/media/sound/SimpleSoundbank.java jdk/src/share/classes/com/sun/media/sound/SoftAbstractResampler.java jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java jdk/src/share/classes/com/sun/media/sound/SoftAudioProcessor.java jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java jdk/src/share/classes/com/sun/media/sound/SoftChannel.java jdk/src/share/classes/com/sun/media/sound/SoftChannelProxy.java jdk/src/share/classes/com/sun/media/sound/SoftChorus.java jdk/src/share/classes/com/sun/media/sound/SoftControl.java jdk/src/share/classes/com/sun/media/sound/SoftCubicResampler.java jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java jdk/src/share/classes/com/sun/media/sound/SoftFilter.java jdk/src/share/classes/com/sun/media/sound/SoftInstrument.java jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java jdk/src/share/classes/com/sun/media/sound/SoftLanczosResampler.java jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler.java jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler2.java jdk/src/share/classes/com/sun/media/sound/SoftLowFrequencyOscillator.java jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java jdk/src/share/classes/com/sun/media/sound/SoftPerformer.java jdk/src/share/classes/com/sun/media/sound/SoftPointResampler.java jdk/src/share/classes/com/sun/media/sound/SoftProcess.java jdk/src/share/classes/com/sun/media/sound/SoftProvider.java jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java jdk/src/share/classes/com/sun/media/sound/SoftResampler.java jdk/src/share/classes/com/sun/media/sound/SoftResamplerStreamer.java jdk/src/share/classes/com/sun/media/sound/SoftReverb.java jdk/src/share/classes/com/sun/media/sound/SoftShortMessage.java jdk/src/share/classes/com/sun/media/sound/SoftSincResampler.java jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java jdk/src/share/classes/com/sun/media/sound/SoftTuning.java jdk/src/share/classes/com/sun/media/sound/SoftVoice.java jdk/src/share/classes/com/sun/media/sound/WaveFloatFileReader.java jdk/src/share/classes/java/awt/Component.java jdk/src/share/classes/java/awt/dnd/DragSourceContext.java jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java jdk/src/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java jdk/src/share/lib/management/management.properties jdk/src/share/native/sun/font/bidi/ubidi.c jdk/src/solaris/classes/sun/nio/ch/NativeThread.java jdk/src/solaris/native/sun/awt/gtk2_interface.c jdk/src/windows/classes/sun/nio/ch/NativeThread.java jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java jdk/test/java/nio/channels/DatagramChannel/NotBound.java jdk/test/java/nio/channels/SocketChannel/AsyncCloseChannel.java jdk/test/java/text/Bidi/Bug6665028.java jdk/test/javax/management/Introspector/LegacyIntrospectorTest.java jdk/test/sun/management/jmxremote/bootstrap/LocalOnlyTest.java jdk/test/sun/net/www/http/ChunkedInputStream/test.txt langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndexEntry.java
diffstat 193 files changed, 27273 insertions(+), 27266 deletions(-) [+]
line wrap: on
line diff
--- a/THIRD_PARTY_README	Fri May 30 00:00:00 2008 +0200
+++ b/THIRD_PARTY_README	Thu Jul 10 00:00:00 2008 +0200
@@ -137,16 +137,6 @@
 The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.
 ____________________________________
 This formulation of W3C's notice and license became active on August 14 1998 so as to improve compatibility with GPL. This version ensures that W3C software licensing terms are no more restrictive than GPL and consequently W3C software may be distributed in GPL packages. See the older formulation for the policy prior to this date. Please see our Copyright FAQ for common questions about using materials from our site, including specific terms and conditions for packages like libwww, Amaya, and Jigsaw. Other questions about this notice can be directed to site-policy@w3.org.

-%% This notice is provided with respect to jscheme.jar, which may be included with this software: 
-Software License Agreement
-Copyright © 1998-2002 by Peter Norvig. 
-Permission is granted to anyone to use this software, in source or object code form, on any computer system, and to modify, compile, decompile, run, and redistribute it to anyone else, subject to the following restrictions: 
-1.The author makes no warranty of any kind, either expressed or implied, about the suitability of this software for any purpose.
-2.The author accepts no liability of any kind for damages or other consequences of the use of this software, even if they arise from defects in the software.
-3.The origin of this software must not be misrepresented, either by explicit claim or by omission.
-4.Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Altered versions may be distributed in packages under other licenses (such as the GNU license). 
-If you find this software useful, it would be nice if you let me (peter@norvig.com) know about it, and nicer still if you send me modifications that you are willing to share. However, you are not required to do so.
 
 
 %% This notice is provided with respect to PC/SC Lite for Suse Linux v. 1.1.1, which may be included with this software: 
--- a/control/make/make/sanity-rules.gmk	Fri May 30 00:00:00 2008 +0200
+++ b/control/make/make/sanity-rules.gmk	Thu Jul 10 00:00:00 2008 +0200
@@ -351,9 +351,6 @@
 ifeq ($(JDK_SRC_AVAILABLE), true)
 	@$(ECHO) "   BUILD_JDK    = $(BUILD_JDK) " >> $(MESSAGE_FILE)
 endif
-ifeq ($(JDK_SRC_AVAILABLE), true)
-	@$(ECHO) "   BUILD_JDK    = $(BUILD_JDK) " >> $(MESSAGE_FILE)
-endif
 ifeq ($(DEPLOY_SRC_AVAILABLE), true)
 	@$(ECHO) "   BUILD_DEPLOY  = $(BUILD_DEPLOY) " >> $(MESSAGE_FILE)
 endif
--- a/corba/make/com/sun/corba/se/sources/Makefile	Fri May 30 00:00:00 2008 +0200
+++ b/corba/make/com/sun/corba/se/sources/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -78,11 +78,11 @@
 POA.MC          = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/POA.mc
 UTIL.MC         = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/Util.mc
 
-MC_GENERATE_CLASS = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-class
-MC_GENERATE_LOG_RB = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-resource 
+MC_GENERATE_CLASS = make-class
+MC_GENERATE_LOG_RB = make-resource 
 
-JSCHEME_GENERATE_CLASS = $(BOOT_JAVA_CMD) jscheme.REPL $(MC_GENERATE_CLASS) 
-JSCHEME_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) jscheme.REPL $(MC_GENERATE_LOG_RB) 
+JSCHEME_GENERATE_CLASS = $(BOOT_JAVA_CMD) com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_CLASS) 
+JSCHEME_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_LOG_RB) 
 
 
 #
--- a/corba/make/sun/rmi/corbalogsources/Makefile	Fri May 30 00:00:00 2008 +0200
+++ b/corba/make/sun/rmi/corbalogsources/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -75,15 +75,14 @@
 POA.MC          = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/POA.mc
 UTIL.MC         = $(SRC_DIR)/com/sun/corba/se/spi/logging/data/Util.mc
 
-MC_GENERATE_CLASS = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-class
-MC_GENERATE_LOG_RB = $(SRC_DIR)/com/sun/tools/corba/se/logutil/scripts/mc.scm -main main make-resource 
+MC_GENERATE_CLASS = make-class
+MC_GENERATE_LOG_RB = make-resource 
 
-JSCHEME_LIB_DIRECTORY=$(SRC_DIR)/com/sun/tools/corba/se/logutil/lib
-JSCHEME_CLASSPATH=$(JSCHEME_LIB_DIRECTORY)/jscheme.jar$(CLASSPATH_SEPARATOR)$(JSCHEME_LIB_DIRECTORY)/jschemelogutil.jar
-JSCHEME_GENERATE_CLASS = $(BOOT_JAVA_CMD) \
-    -cp "$(JSCHEME_CLASSPATH)" jscheme.REPL $(MC_GENERATE_CLASS) 
-JSCHEME_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) \
-    -cp "$(JSCHEME_CLASSPATH)" jscheme.REPL $(MC_GENERATE_LOG_RB) 
+MC_CLASSPATH=$(BUILDTOOLJARDIR)/MC.jar
+MCJ_GENERATE_CLASS = $(BOOT_JAVA_CMD) \
+    -cp "$(MC_CLASSPATH)" com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_CLASS) 
+MCJ_GENERATE_LOG_RB = $(BOOT_JAVA_CMD) \
+    -cp "$(MC_CLASSPATH)" com.sun.tools.corba.se.logutil.MC $(MC_GENERATE_LOG_RB) 
 
 
 #
@@ -104,28 +103,28 @@
 	$(MKDIR) -p $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/ActivationSystemException.java : $(ACTIVATION.MC)
-	$(JSCHEME_GENERATE_CLASS) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/IORSystemException.java : $(IOR.MC)
-	$(JSCHEME_GENERATE_CLASS) $(IOR.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(IOR.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/InterceptorsSystemException.java : $(INTERCEPTORS.MC)
-	$(JSCHEME_GENERATE_CLASS) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/NamingSystemException.java : $(NAMING.MC)
-	$(JSCHEME_GENERATE_CLASS) $(NAMING.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(NAMING.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/OMGSystemException.java : $(OMG.MC)
-	$(JSCHEME_GENERATE_CLASS) $(OMG.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(OMG.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/ORBUtilSystemException.java : $(ORBUTIL.MC)
-	$(JSCHEME_GENERATE_CLASS) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/POASystemException.java : $(POA.MC)
-	$(JSCHEME_GENERATE_CLASS) $(POA.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(POA.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/UtilSystemException.java : $(UTIL.MC)
-	$(JSCHEME_GENERATE_CLASS) $(UTIL.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_CLASS) $(UTIL.MC) $(LOG_GENDIRECTORY)
 
 logresource.generate: $(LOG_GENDIRECTORY)/LogStrings.properties
 
@@ -142,28 +141,28 @@
 	$(CAT) $(LOG_GENDIRECTORY)/*.resource > $(LOG_GENDIRECTORY)/LogStrings.properties
 
 $(LOG_GENDIRECTORY)/ActivationSystemException.resource : $(ACTIVATION.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(ACTIVATION.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/IORSystemException.resource : $(IOR.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(IOR.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(IOR.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/InterceptorsSystemException.resource : $(INTERCEPTORS.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(INTERCEPTORS.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/NamingSystemException.resource : $(NAMING.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(NAMING.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(NAMING.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/OMGSystemException.resource : $(OMG.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(OMG.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(OMG.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/ORBUtilSystemException.resource : $(ORBUTIL.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(ORBUTIL.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/POASystemException.resource : $(POA.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(POA.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(POA.MC) $(LOG_GENDIRECTORY)
 
 $(LOG_GENDIRECTORY)/UtilSystemException.resource : $(UTIL.MC)
-	$(JSCHEME_GENERATE_LOG_RB) $(UTIL.MC) $(LOG_GENDIRECTORY)
+	$(MCJ_GENERATE_LOG_RB) $(UTIL.MC) $(LOG_GENDIRECTORY)
 
 
 #
--- a/corba/make/tools/Makefile	Fri May 30 00:00:00 2008 +0200
+++ b/corba/make/tools/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -33,6 +33,7 @@
 SUBDIRS =                   \
   strip_properties          \
   idlj                      \
+  logutil		    \
 
 all build clean clobber::
 	$(SUBDIRS-loop)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/make/tools/logutil/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# Makefile for building the idlj tool
+#
+
+BUILDDIR = ../..
+PACKAGE = com.sun.tools.corba.se.logutil
+PRODUCT = tools
+PROGRAM = MC
+include $(BUILDDIR)/common/Defs.gmk
+
+BUILDTOOL_SOURCE_ROOT = $(SHARE_SRC)/classes
+BUILDTOOL_MAIN        = $(PKGDIR)/MC.java
+
+#
+# Build tool jar rules.
+#
+include $(BUILDDIR)/common/BuildToolJar.gmk
+
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/first.set	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/first.set	Thu Jul 10 00:00:00 2008 +0200
@@ -1,11 +1,35 @@
+/*
+ * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
 /*
  *    COMPONENT_NAME:  idl.parser
- *                                                 
+ *
  *    ORIGINS: 27
  *
- *    THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM                        
  *    5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
- *                                        
+ *
  */
 
 CORBA IDL
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/follow.set	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/follow.set	Thu Jul 10 00:00:00 2008 +0200
@@ -1,11 +1,35 @@
+/*
+ * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
 /*
  *    COMPONENT_NAME:  idl.parser
- *                                                 
+ *
  *    ORIGINS: 27
  *
- *    THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM                        
  *    5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
- *                                        
+ *
  */
 
 CORBA IDL
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/grammar.idl	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/grammar.idl	Thu Jul 10 00:00:00 2008 +0200
@@ -1,14 +1,38 @@
+/*
+ * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
 /*
  *    COMPONENT_NAME:  idl.parser
- *                                                 
+ *
  *    ORIGINS: 27
  *
- *    THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM                        
  *    5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
- *                                        
+ *
  */
 
-CORBA 2.3 IDL 
+CORBA 2.3 IDL
 ---------------
 
 (1) <specification>	<definition><specification'>
@@ -83,7 +107,7 @@
 
 (16) <vad>		e
 			<export> <vad>
-		
+
 (17) <value_dcl>	<value_header> "{" <value_element> <ve> "}"
 
 (17) <ve>		e
@@ -91,9 +115,9 @@
 
 (18) <value_header>	"custom" "valuetype" <id> <value_inheritance_spec>
 			"valuetype" <id> <value_inheritance_spec>
-			"custom" "valuetype" <id> 
-			"valuetype" <id> 
-			
+			"custom" "valuetype" <id>
+			"valuetype" <id>
+
 (19) <value_inheritance_spec>	<opt_inherits> <opt_supports>
 
 (19) <opt_inherits>	e
@@ -107,7 +131,7 @@
 			"supports" <interface_name> <interface_name_list>
 
 (19) <interface_name_list>  e
-			"," <interface_name> <interface_name_list> 
+			"," <interface_name> <interface_name_list>
 
 (20) <value_name>	<scoped_name>
 
@@ -121,7 +145,7 @@
 (23) <init_dcl>		"factory" <id> "(" ")"
 			"factory" <id> "(" <init_param_dcls> ")"
 
-(24) <init_param_dcls>	<init_param_decl> 
+(24) <init_param_dcls>	<init_param_decl>
 			<init_param_decl> "," <init_param_dcls>
 
 (25) <init_param_dcl>	<init_param_attribute> <param_type_spec> <simple_declarator>
@@ -349,7 +373,7 @@
 
 (87) <op_dcl''>		e
 			<context_expr>
-			<raises_expr> 
+			<raises_expr>
 			<raises_expr> <context_expr>
 
 (88) <op_attribute>	"oneway"
@@ -386,7 +410,7 @@
 			<wide_string_type>
 			<scoped_name>
 
-(96) <fixed_pt_type>	"fixed" "<" <positive_int_const> "," <positive_int_const> ">" 
+(96) <fixed_pt_type>	"fixed" "<" <positive_int_const> "," <positive_int_const> ">"
 
 (97) <fixed_pt_const_type> "fixed"
 
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/grammar3.idl	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/grammar3.idl	Thu Jul 10 00:00:00 2008 +0200
@@ -1,11 +1,35 @@
+/*
+ * Copyright 1999 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
 /*
  *    COMPONENT_NAME:  idl.parser
- *                                                 
+ *
  *    ORIGINS: 27
  *
- *    THIS PRODUCT CONTAINS RESTRICTED MATERIALS OF IBM                        
  *    5639-D57, (C) COPYRIGHT International Business Machines Corp., 1997, 1998
- *                                        
+ *
  */
 
 (1) <specification>	<imports> <definition> <specification'> // CORBA3
@@ -98,7 +122,7 @@
 
 (16) <vad>		e
 			<export> <vad>
-		
+
 (17) <value_dcl>	<value_header> "{" <value_element> <ve> "}"
 
 (17) <ve>		e
@@ -106,9 +130,9 @@
 
 (18) <value_header>	"custom" "valuetype" <id> <value_inheritance_spec>
 			"valuetype" <id> <value_inheritance_spec>
-			"custom" "valuetype" <id> 
-			"valuetype" <id> 
-			
+			"custom" "valuetype" <id>
+			"valuetype" <id>
+
 (19) <value_inheritance_spec>	<opt_inherits> <opt_supports>
 
 (19) <opt_inherits>	e
@@ -122,7 +146,7 @@
 			"supports" <interface_name> <interface_name_list>
 
 (19) <interface_name_list>  e
-			"," <interface_name> <interface_name_list> 
+			"," <interface_name> <interface_name_list>
 
 (20) <value_name>	<scoped_name>
 
@@ -136,7 +160,7 @@
 (23) <init_dcl>		"factory" <id> "(" ")"
 			"factory" <id> "(" <init_param_dcls> ")"
 
-(24) <init_param_dcls>	<init_param_dcl> 
+(24) <init_param_dcls>	<init_param_dcl>
 			<init_param_dcl> "," <init_param_dcls>
 
 (25) <init_param_dcl>	<init_param_attribute> <param_type_spec> <simple_declarator>
@@ -351,7 +375,7 @@
 (85) <readonly_attr_spec>   <readonly_attr_header> <readonly_attr_declarator>	// CORBA3
 
 (85) <readonly_attr_header> "readonly" "attribute" <param_type_spec>	// CORBA3
-			
+
 (85) <readonly_attr_declarator> <simple_declarator> <get_excep_expr>	// CORBA3
 			<simple_declarator> <sds>   // CORBA3
 
@@ -389,7 +413,7 @@
 
 (87) <op_dcl''>		e
 			<context_expr>
-			<raises_expr> 
+			<raises_expr>
 			<raises_expr> <context_expr>
 
 (88) <op_attribute>	"oneway"
@@ -426,7 +450,7 @@
 			<wide_string_type>
 			<scoped_name>
 
-(96) <fixed_pt_type>	"fixed" "<" <positive_int_const> "," <positive_int_const> ">" 
+(96) <fixed_pt_type>	"fixed" "<" <positive_int_const> "," <positive_int_const> ">"
 
 (97) <fixed_pt_const_type> "fixed"
 
@@ -450,7 +474,7 @@
 
 (204) <snames>		e
 			"," <scoped_name> <snames>
-			
+
 (205) <component_inheritance_spec> ":" <scoped_name>
 
 (206) <component_body>	<component_export> <ces>
@@ -458,8 +482,8 @@
 (206) <ces>		e
 			<component_export> <ces>
 
-(207) <component_export>    <provides_dcl> ";" 
-			<uses_dcl> ";" 
+(207) <component_export>    <provides_dcl> ";"
+			<uses_dcl> ";"
 			<emits_dcl> ";"
 			<publishes_dcl> ";"
 			<consumes_dcl> ";"
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl.prp	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl.prp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,3 +1,28 @@
+#
+# Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
 #
 # COMPONENT_NAME:  idl.parser
 #
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_ja.prp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,3 +1,28 @@
+#
+# Copyright 1999-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
 #
 # COMPONENT_NAME:  idl.parser
 #
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/idl_zh_CN.prp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,3 +1,28 @@
+#
+# Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
 #
 # COMPONENT_NAME:  idl.parser
 #
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,3 +1,28 @@
+#
+# Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
 #
 # COMPONENT_NAME: idl.toJava
 #
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_ja.prp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,3 +1,28 @@
+#
+# Copyright 2001-2005 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
 #
 # COMPONENT_NAME: idl.toJava
 #
--- a/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable_zh_CN.prp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,3 +1,28 @@
+#
+# Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
 #
 # COMPONENT_NAME: idl.toJava
 #
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/IndentingPrintWriter.java	Fri May 30 00:00:00 2008 +0200
+++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/IndentingPrintWriter.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright 2003, 2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
 import java.io.OutputStream ;
 import java.io.BufferedWriter ;
 import java.io.OutputStreamWriter ;
-import jsint.Pair ;
 import java.util.StringTokenizer ;
 
 public class IndentingPrintWriter extends PrintWriter {
@@ -38,22 +37,20 @@
     private int indentWidth = 4 ;
     private String indentString = "" ;
 
-    public void printMsg( String msg, Pair data )
+    public void printMsg( String msg, Object... data )
     {
         // System.out.println( "printMsg called with msg=" + msg + " data=" + data ) ;
         StringTokenizer st = new StringTokenizer( msg, "@", true ) ;
         StringBuffer result = new StringBuffer() ;
-        Object head = data.first ;
-        Pair tail = (Pair)data.rest ;
         String token = null ;
+	int pos = 0;
 
         while (st.hasMoreTokens()) {
             token = st.nextToken() ;
             if (token.equals("@")) {
-                if (head != null) {
-                    result.append( head ) ;
-                    head = tail.first ;
-                    tail = (Pair)tail.rest ;
+                if (pos < data.length) {
+                    result.append( data[pos] ) ;
+		    ++pos;
                 } else {
                     throw new Error( "List too short for message" ) ;
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/Input.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.corba.se.logutil;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStreamReader;
+import java.io.IOException;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class Input {
+
+  /**
+   * The name of the package this class will inhabit.
+   */
+  private String packageName;
+
+  /**
+   * The name of the generated class.
+   */
+  private String className;
+
+  /**
+   * The name of the group of exceptions handled by the class.
+   */
+  private String groupName;
+
+  /**
+   * The group of exceptions.
+   */
+  private Queue<InputException> exceptions;
+
+  /**
+   * Represents the current state of parsing the input.
+   */
+  private enum State
+  {
+    OUTER,
+    IN_CLASS,
+    IN_EXCEPTION_LIST
+  };
+
+  /**
+   * Regular expression to match each code line.
+   */
+  private static final Pattern EXCEPTION_INFO_REGEX = 
+    Pattern.compile("(\\w+)\\s*(\\d+)\\s*(\\w+)");
+
+  /**
+   * Parses the specified file to create a new {@link Input}
+   * object.
+   *
+   * @param filename the file to parse.
+   * @throws FileNotFoundException if the file can't be found.
+   * @throws IOException if an I/O error occurs.
+   */
+  public Input(final String filename) 
+  throws FileNotFoundException, IOException {
+    BufferedReader r =
+      new BufferedReader(new InputStreamReader(new FileInputStream(filename)));
+    State state = State.OUTER;
+    InputException current = null;
+    exceptions = new LinkedList<InputException>();
+    String line;
+    while ((line = r.readLine()) != null) {
+      // Skip ; comments
+      if (line.startsWith(";"))
+	continue;
+
+      int index = line.indexOf("(");
+      if (index == -1)
+	continue;
+      
+      switch (state) {
+      case OUTER:
+	state = State.IN_CLASS;
+	String[] classInfo = line.substring(index).split(" ");
+	packageName = classInfo[0].substring(2, classInfo[0].length() - 1);
+	className = classInfo[1].substring(1, classInfo[1].length() - 1);
+	groupName = classInfo[2];
+	break;
+      case IN_CLASS:
+	state = State.IN_EXCEPTION_LIST;
+	break;
+      case IN_EXCEPTION_LIST:
+	boolean inQuote = false;
+	boolean inCode = false;
+	boolean end = false;
+	int start = index + 1;
+	Queue<String> lines = new LinkedList<String>();
+	for (int a = start; a < line.length(); ++a) {
+	  if (line.charAt(a) == '(' && !inCode && !inQuote) {
+	    if (current == null) 
+	      current =
+		new InputException(line.substring(start, a).trim());
+	    start = a + 1;
+	    inCode = true;
+	  }
+	  if (line.charAt(a) == '"')
+	    inQuote = !inQuote;
+	  if (line.charAt(a) == ')' && !inQuote) {
+	    if (inCode) {
+	      lines.offer(line.substring(start, a));
+	      inCode = false;
+	    } else 
+	      end = true;
+	  }
+	  if (!end && a == line.length() - 1)
+	    line += r.readLine();
+	}
+	for (String l : lines) {
+	  int stringStart = l.indexOf("\"") + 1;
+	  int stringEnd = l.indexOf("\"", stringStart);
+	  Matcher matcher = EXCEPTION_INFO_REGEX.matcher(l.substring(0, stringStart));
+	  if (matcher.find())
+	    current.add(new InputCode(matcher.group(1),
+				      Integer.parseInt(matcher.group(2)),
+				      matcher.group(3),
+				      l.substring(stringStart, stringEnd)));
+	}
+	exceptions.offer(current);
+	current = null;
+	break;
+      }
+    }
+  }
+
+  /**
+   * Returns the name of this group of exceptions.
+   *
+   * @return the name of this group of exceptions.
+   */
+  public String getGroupName()
+  {
+    return groupName;
+  }
+
+  /**
+   * Returns the name of the package this class will go in.
+   *
+   * @return the name of the package.
+   */
+  public String getPackageName()
+  {
+    return packageName;
+  }
+
+  /**
+   * Returns the name of the generated class.
+   *
+   * @return the name of the class.
+   */
+  public String getClassName()
+  {
+    return className;
+  }
+
+  /**
+   * Returns the exceptions contained in this class.
+   *
+   * @return the exceptions.
+   */
+  public Queue<InputException> getExceptions() {
+    return exceptions;
+  }
+
+  /**
+   * Returns a textual representation of this input.
+   *
+   * @return a textual representation.
+   */
+  public String toString() {
+    return getClass().getName() +
+      "[packageName=" + packageName +
+      ",className=" + className +
+      ",groupName=" + groupName +
+      ",exceptions=" + exceptions +
+      "]";
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/InputCode.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.tools.corba.se.logutil;
+
+public class InputCode {
+
+  /**
+   * The name of this code.
+   */
+  private final String name;
+
+  /**
+   * The code.
+   */
+  private final int code;
+
+  /**
+   * The log level for this code.
+   */
+  private final String logLevel;
+
+  /**
+   * The error message for this code.
+   */
+  private final String message;
+
+  /**
+   * Creates a new error code with the specified name, code,
+   * log level and error message.
+   *
+   * @param name the name of the new code.
+   * @param code the code itself.
+   * @param logLevel the level of severity of this error.
+   * @param message the error message for this code.
+   */
+  public InputCode(final String name, final int code,
+		   final String logLevel, final String message) {
+    this.name = name;
+    this.code = code;
+    this.logLevel = logLevel;
+    this.message = message;
+  }
+
+  /**
+   * Returns the name of this code.
+   *
+   * @return the name of the code.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Returns the code.
+   *
+   * @return the code.
+   */
+  public int getCode() {
+    return code;
+  }
+
+  /**
+   * Returns the severity of this code.
+   *
+   * @return the log level severity of the code.
+   */
+  public String getLogLevel() {
+    return logLevel;
+  }
+
+  /**
+   * Returns the error message for this code.
+   *
+   * @return the error message for this code.
+   */
+  public String getMessage() {
+    return message;
+  }
+
+  /**
+   * Returns a textual representation of this code.
+   *
+   * @return a textual representation.
+   */
+  public String toString() {
+    return getClass().getName() +
+      "[name=" + name +
+      ",code=" + code +
+      ",logLevel=" + logLevel +
+      ",message=" + message +
+      "]";
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/InputException.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.tools.corba.se.logutil;
+
+import java.util.LinkedList;
+import java.util.Queue;
+
+public class InputException {
+
+  /**
+   * The name of this exception.
+   */
+  private final String name;
+
+  /**
+   * The codes associated with this exception.
+   */
+  private final Queue<InputCode> codes;
+
+  /**
+   * Constructs a new {@link InputException} with the
+   * specified name.
+   * 
+   * @param name the name of the new exception;
+   */
+  public InputException(final String name) {
+    this.name = name;
+    codes = new LinkedList<InputCode>();
+  }
+
+  /**
+   * Adds a new code to this exception.
+   *
+   * @param c the code to add.
+   */
+  public void add(InputCode c)
+  {
+    codes.offer(c);
+  }
+
+  /**
+   * Returns the name of this exception.
+   *
+   * @return the exception's name.
+   */
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Returns the codes associated with this exception.
+   *
+   * @return the exception's codes.
+   */
+  public Queue<InputCode> getCodes() {
+    return codes;
+  }
+
+  /**
+   * Returns a textual representation of this exception.
+   *
+   * @return a textual representation.
+   */
+  public String toString() {
+    return getClass().getName()
+      + "[name=" + name
+      + ",codes=" + codes 
+      + "]";
+  }
+
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/corba/src/share/classes/com/sun/tools/corba/se/logutil/MC.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,559 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.tools.corba.se.logutil;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Formatter;
+import java.util.List;
+import java.util.Queue;
+
+public class MC {
+
+  private static final String VERSION = "1.0";
+
+  private static final List<String> SUN_EXCEPTION_GROUPS = Arrays.asList(new String[]
+    { "SUNBASE", "ORBUTIL", "ACTIVATION", "NAMING", "INTERCEPTORS", "POA", "IOR", "UTIL" });
+
+  private static final List<String> EXCEPTIONS = Arrays.asList(new String[]
+    { "UNKNOWN", "BAD_PARAM", "NO_MEMORY", "IMP_LIMIT", "COMM_FAILURE", "INV_OBJREF", "NO_PERMISSION",
+      "INTERNAL", "MARSHAL", "INITIALIZE", "NO_IMPLEMENT", "BAD_TYPECODE", "BAD_OPERATION", "NO_RESOURCES", 
+      "NO_RESPONSE", "PERSIST_STORE", "BAD_INV_ORDER", "TRANSIENT", "FREE_MEM", "INV_IDENT", "INV_FLAG", 
+      "INTF_REPOS", "BAD_CONTEXT", "OBJ_ADAPTER", "DATA_CONVERSION", "OBJECT_NOT_EXIST", "TRANSACTION_REQUIRED", 
+      "TRANSACTION_ROLLEDBACK", "INVALID_TRANSACTION", "INV_POLICY", "CODESET_INCOMPATIBLE", "REBIND",
+      "TIMEOUT", "TRANSACTION_UNAVAILABLE", "BAD_QOS", "INVALID_ACTIVITY", "ACTIVITY_COMPLETED", 
+      "ACTIVITY_REQUIRED" });
+
+  /**
+   * Read the minor codes from the input file and
+   * write out a resource file.
+   *
+   * @param inFile the file to read the codes from.
+   * @param outDir the directory to write the resource file to.
+   * @throws FileNotFoundException if the input file can not be found.
+   * @throws IOException if an I/O error occurs.
+   */ 
+  private void makeResource(String inFile, String outDir) 
+  throws FileNotFoundException, IOException {
+    writeResource(outDir, new Input(inFile));
+  }
+
+  /**
+   * Create a new Java source file using the specified Scheme input file,
+   * and writing the result to the given output directory.
+   *
+   * @param inFile the file to read the data from.
+   * @param outDir the directory to write the Java class to.
+   * @throws FileNotFoundException if the input file can not be found.
+   * @throws IOException if an I/O error occurs.
+   */
+  private void makeClass(String inFile, String outDir) 
+  throws FileNotFoundException, IOException {
+    writeClass(inFile, outDir, new Input(inFile));
+  }
+
+  /**
+   * Writes out a Java source file using the data from the given
+   * {@link Input} object.  The result is written to {@code outDir}.
+   * The name of the input file is just used in the header of the
+   * resulting source file.
+   *
+   * @param inFile the name of the file the data was read from.
+   * @param outDir the directory to write the Java class to.
+   * @param input the parsed input data.
+   * @throws FileNotFoundException if the output file can't be written.
+   */ 
+  private void writeClass(String inFile, String outDir, Input input)
+    throws FileNotFoundException {
+    String packageName = input.getPackageName();
+    String className = input.getClassName();
+    String groupName = input.getGroupName();
+    Queue<InputException> exceptions = input.getExceptions();
+    FileOutputStream file = new FileOutputStream(outDir + File.separator + className + ".java");
+    IndentingPrintWriter pw = new IndentingPrintWriter(file);
+
+    writeClassHeader(inFile, groupName, pw);
+    pw.printMsg("package @ ;", packageName);
+    pw.println();
+    pw.println("import java.util.logging.Logger ;");
+    pw.println("import java.util.logging.Level ;");
+    pw.println();
+    pw.println("import org.omg.CORBA.OMGVMCID ;");
+    pw.println( "import com.sun.corba.se.impl.util.SUNVMCID ;");
+    pw.println( "import org.omg.CORBA.CompletionStatus ;");
+    pw.println( "import org.omg.CORBA.SystemException ;");
+    pw.println();
+    pw.println( "import com.sun.corba.se.spi.orb.ORB ;");
+    pw.println();
+    pw.println( "import com.sun.corba.se.spi.logging.LogWrapperFactory;");
+    pw.println();
+    pw.println( "import com.sun.corba.se.spi.logging.LogWrapperBase;");
+    pw.println();
+    writeImports(exceptions, pw);
+    pw.println();
+    pw.indent();
+    pw.printMsg("public class @ extends LogWrapperBase {", className);
+    pw.println();
+    pw.printMsg("public @( Logger logger )", className);
+    pw.indent();
+    pw.println( "{");
+    pw.undent();
+    pw.println( "super( logger ) ;");
+    pw.println( "}");
+    pw.println();
+    pw.flush();
+    writeFactoryMethod(className, groupName, pw);
+    writeExceptions(groupName, exceptions, className, pw);
+    pw.undent();
+    pw.println( );
+    pw.println( "}");
+    pw.flush();
+    pw.close();
+  }
+
+  /**
+   * Writes out the header of a Java source file.
+   *
+   * @param inFile the input file the file was generated from.
+   * @param groupName the group of exceptions the Java source file is for.
+   * @param pw the print writer used to write the output.
+   */
+  private void writeClassHeader(String inFile, String groupName,
+				IndentingPrintWriter pw) {
+    if (groupName.equals("OMG"))
+      pw.println("// Log wrapper class for standard exceptions");
+    else
+      pw.printMsg("// Log wrapper class for Sun private system exceptions in group @",
+		  groupName);
+    pw.println("//");
+    pw.printMsg("// Generated by MC.java version @, DO NOT EDIT BY HAND!", VERSION);
+    pw.printMsg("// Generated from input file @ on @", inFile, new Date());
+    pw.println();
+  }
+
+  /**
+   * Write out the import list for the exceptions.
+   *
+   * @param groups the exceptions that were parsed.
+   * @param pw the {@link IndentingPrintWriter} for writing to the file.
+   */
+  private void writeImports(Queue<InputException> exceptions,
+			    IndentingPrintWriter pw) {
+    if (exceptions == null)
+      return;
+    for (InputException e : exceptions) 
+      pw.println("import org.omg.CORBA." + e.getName() + " ;");
+  }
+
+  /**
+   * Write out the factory method for this group of exceptions.
+   *
+   * @param className the name of the generated class.
+   * @param groupName the name of this group of exceptions.
+   * @param pw the {@link IndentingPrintWriter} for writing to the file.
+   */
+  private void writeFactoryMethod(String className, String groupName,
+				  IndentingPrintWriter pw) {
+    pw.indent();
+    pw.println( "private static LogWrapperFactory factory = new LogWrapperFactory() {");
+    pw.println( "public LogWrapperBase create( Logger logger )" );
+    pw.indent();
+    pw.println( "{");
+    pw.undent();
+    pw.printMsg("return new @( logger ) ;", className);
+    pw.undent();
+    pw.println( "}" );
+    pw.println( "} ;" );
+    pw.println();
+    pw.printMsg("public static @ get( ORB orb, String logDomain )", className);
+    pw.indent();
+    pw.println( "{");
+    pw.indent();	
+    pw.printMsg( "@ wrapper = ", className);
+    pw.indent();
+    pw.printMsg( "(@) orb.getLogWrapper( logDomain, ", className);
+    pw.undent();	
+    pw.undent();	
+    pw.printMsg( "\"@\", factory ) ;", groupName);
+    pw.undent();	
+    pw.println( "return wrapper ;" );
+    pw.println( "} " );
+    pw.println();
+    pw.printMsg( "public static @ get( String logDomain )", className);
+    pw.indent();	
+    pw.println( "{");
+    pw.indent();	
+    pw.printMsg( "@ wrapper = ", className);
+    pw.indent();
+    pw.printMsg( "(@) ORB.staticGetLogWrapper( logDomain, ", className);
+    pw.undent();	
+    pw.undent();	
+    pw.printMsg( "\"@\", factory ) ;", groupName);
+    pw.undent();	
+    pw.println( "return wrapper ;" );
+    pw.println( "} " );
+    pw.println();
+  }
+
+  /**
+   * Writes out the exceptions themselves.
+   *
+   * @param groupName the name of this group of exceptions.
+   * @param exceptions the exceptions to write out.
+   * @param className the name of the generated class.
+   * @param pw the {@link IndentingPrintWriter} for writing to the file.
+   */
+  private void writeExceptions(String groupName, Queue<InputException> exceptions, 
+			       String className, IndentingPrintWriter pw) {
+    for (InputException e : exceptions) {
+      pw.println("///////////////////////////////////////////////////////////");
+      pw.printMsg("// @", e.getName());
+      pw.println("///////////////////////////////////////////////////////////");
+      pw.println();
+      for (InputCode c : e.getCodes()) 
+	writeMethods(groupName, e.getName(), c.getName(), c.getCode(),
+		     c.getLogLevel(), className, StringUtil.countArgs(c.getMessage()), pw);     
+      pw.flush();
+    }
+  }
+
+  /**
+   * Writes out the methods for a particular error.
+   *
+   * @param groupName the name of this group of exceptions.
+   * @param exceptionName the name of this particular exception.
+   * @param errorName the name of this particular error.
+   * @param code the minor code for this particular error.
+   * @param ident the name of the error in mixed-case identifier form.
+   * @param level the level at which to place log messages.
+   * @param className the name of the class for this group of exceptions.
+   * @param numParams the number of parameters the detail message takes.
+   * @param pw the print writer for writing to the file.
+   */
+  private void writeMethods(String groupName, String exceptionName, String errorName,
+			    int code, String level, String className, int numParams,
+			    IndentingPrintWriter pw) {
+    String ident = StringUtil.toMixedCase(errorName);
+    pw.printMsg("public static final int @ = @ ;", errorName, getBase(groupName, code));
+    pw.println();
+    pw.flush();
+    writeMethodStatusCause(groupName, exceptionName, errorName, ident, level,
+			   numParams, className, pw);
+    pw.println();
+    pw.flush();
+    writeMethodStatus(exceptionName, ident, numParams, pw);
+    pw.println();
+    pw.flush();
+    writeMethodCause(exceptionName, ident, numParams, pw);
+    pw.println();
+    pw.flush();
+    writeMethodNoArgs(exceptionName, ident, numParams, pw);
+    pw.println();
+    pw.flush();
+  }
+
+  /**
+   * Writes out a method for an error that takes a
+   * {@link org.omg.CORBA.CompletionStatus} and a cause.
+   *
+   * @param groupName the name of this group of exceptions.
+   * @param exceptionName the name of this particular exception.
+   * @param errorName the name of this particular error.
+   * @param ident the name of the error in mixed-case identifier form.
+   * @param logLevel the level at which to place log messages.
+   * @param numParams the number of parameters the detail message takes.
+   * @param className the name of the class for this group of exceptions.
+   * @param pw the print writer for writing to the file.
+   */
+  private void writeMethodStatusCause(String groupName, String exceptionName,
+				      String errorName, String ident,
+				      String logLevel, int numParams,
+				      String className, IndentingPrintWriter pw) {
+    pw.indent();
+    pw.printMsg( "public @ @( CompletionStatus cs, Throwable t@) {", exceptionName,
+		 ident, makeDeclArgs(true, numParams));
+    pw.printMsg( "@ exc = new @( @, cs ) ;", exceptionName, exceptionName, errorName);
+    pw.indent();
+    pw.println( "if (t != null)" );
+    pw.undent();
+    pw.println( "exc.initCause( t ) ;" );	
+    pw.println();
+    pw.indent();
+    pw.printMsg( "if (logger.isLoggable( Level.@ )) {", logLevel);
+    if (numParams > 0) {
+      pw.printMsg( "Object[] parameters = new Object[@] ;", numParams);
+      for (int a = 0; a < numParams; ++a)
+	pw.printMsg("parameters[@] = arg@ ;", a, a);
+    } else 
+      pw.println( "Object[] parameters = null ;");
+    pw.indent();
+    pw.printMsg( "doLog( Level.@, \"@.@\",", logLevel, groupName, ident);
+    pw.undent();
+    pw.undent();
+    pw.printMsg( "parameters, @.class, exc ) ;", className);
+    pw.println( "}");
+    pw.println();
+    
+    pw.undent();
+    pw.println( "return exc ;");
+    pw.println( "}");
+  }
+
+  /**
+   * Writes out a method for an error that takes a
+   * {@link org.omg.CORBA.CompletionStatus}.
+   *
+   * @param exceptionName the name of this particular exception.
+   * @param ident the name of the error in mixed-case identifier form.
+   * @param numParams the number of parameters the detail message takes.
+   * @param pw the print writer for writing to the file.
+   */
+  private void writeMethodStatus(String exceptionName, String ident,
+				 int numParams, IndentingPrintWriter pw) {
+    pw.indent();
+    pw.printMsg("public @ @( CompletionStatus cs@) {", exceptionName,
+		ident, makeDeclArgs(true, numParams));
+    pw.undent();
+    pw.printMsg("return @( cs, null@ ) ;", ident, makeCallArgs(true, numParams));
+    pw.println("}");
+  }
+
+  /**
+   * Writes out a method for an error that takes a cause.
+   *
+   * @param exceptionName the name of this particular exception.
+   * @param ident the name of the error in mixed-case identifier form.
+   * @param numParams the number of parameters the detail message takes.
+   * @param pw the print writer for writing to the file.
+   */
+  private void writeMethodCause(String exceptionName, String ident,
+				int numParams, IndentingPrintWriter pw) {
+    pw.indent();
+    pw.printMsg("public @ @( Throwable t@) {", exceptionName, ident,
+		makeDeclArgs(true, numParams));
+    pw.undent();
+    pw.printMsg("return @( CompletionStatus.COMPLETED_NO, t@ ) ;", ident,
+		makeCallArgs(true, numParams));
+    pw.println("}");
+  }
+
+  /**
+   * Writes out a method for an error that takes no arguments.
+   *
+   * @param exceptionName the name of this particular exception.
+   * @param ident the name of the error in mixed-case identifier form.
+   * @param numParams the number of parameters the detail message takes.
+   * @param pw the print writer for writing to the file.
+   */
+  private void writeMethodNoArgs(String exceptionName, String ident,
+				 int numParams, IndentingPrintWriter pw) {
+    
+    pw.indent();
+    pw.printMsg("public @ @( @) {", exceptionName, ident,
+		makeDeclArgs(false, numParams));
+    pw.undent();
+    pw.printMsg("return @( CompletionStatus.COMPLETED_NO, null@ ) ;",
+		ident, makeCallArgs(true, numParams));
+    pw.println("}");
+  }
+
+  /**
+   * Returns a list of comma-separated arguments with type declarations.
+   *
+   * @param leadingComma true if the list should start with a comma.
+   * @param numArgs the number of arguments to generate.
+   * @return the generated string.
+   */
+  private String makeDeclArgs(boolean leadingComma, int numArgs) {
+    return makeArgString("Object arg", leadingComma, numArgs);
+  }
+
+  /**
+   * Returns a list of comma-separated arguments without type declarations.
+   *
+   * @param leadingComma true if the list should start with a comma.
+   * @param numArgs the number of arguments to generate.
+   * @return the generated string.
+   */
+  private String makeCallArgs(boolean leadingComma, int numArgs) {
+    return makeArgString("arg", leadingComma, numArgs);
+  }
+
+  /**
+   * Returns a list of comma-separated arguments.
+   *
+   * @param prefixString the string with which to prefix each argument.
+   * @param leadingComma true if the list should start with a comma.
+   * @param numArgs the number of arguments to generate.
+   * @return the generated string.
+   */
+  private String makeArgString(String prefixString, boolean leadingComma,
+			       int numArgs) {
+    if (numArgs == 0)
+      return " ";
+    if (numArgs == 1) {
+      if (leadingComma)
+	return ", " + prefixString + (numArgs - 1);
+      else
+	return " " + prefixString + (numArgs - 1);
+    }
+    return makeArgString(prefixString, leadingComma, numArgs - 1) +
+      ", " + prefixString + (numArgs - 1);
+  }
+
+  /**
+   * Returns the {@link String} containing the calculation of the
+   * error code.
+   *
+   * @param groupName the group of exception to which the code belongs.
+   * @param code the minor code number representing the exception within the group.
+   * @return the unique error code.
+   */
+  private String getBase(String groupName, int code) {
+    if (groupName.equals("OMG"))
+      return "OMGVMCID.value + " + code;
+    else
+      return "SUNVMCID.value + " + (code + getSunBaseNumber(groupName));
+  }
+
+  /**
+   * Returns the base number for Sun-specific exceptions.
+   *
+   * @return the base number.
+   */
+  private int getSunBaseNumber(String groupName) {
+    return 200 * SUN_EXCEPTION_GROUPS.indexOf(groupName);
+  }
+
+  /**
+   * Writes out a resource file using the data from the given
+   * {@link Input} object.  The result is written to {@code outDir}.
+   *
+   * @param outDir the directory to write the Java class to.
+   * @param input the parsed input data.
+   * @throws FileNotFoundException if the output file can't be written.
+   */ 
+  private void writeResource(String outDir, Input input)
+    throws FileNotFoundException { 
+    FileOutputStream file = new FileOutputStream(outDir + File.separator +
+						 input.getClassName() + ".resource");
+    IndentingPrintWriter pw = new IndentingPrintWriter(file);
+    String groupName = input.getGroupName();
+    for (InputException e : input.getExceptions()) {
+      String exName = e.getName();
+      for (InputCode c : e.getCodes()) {
+	String ident = StringUtil.toMixedCase(c.getName());
+	pw.printMsg("@.@=\"@: (@) @\"", groupName, ident,
+		    getMessageID(groupName, exName, c.getCode()), exName, c.getMessage());
+      }
+      pw.flush();
+    }
+    pw.close();
+  }
+    
+  /**
+   * Returns the message ID corresponding to the given group name,
+   * exception name and error code.
+   *
+   * @param groupName the name of the group of exceptions.
+   * @param exception the name of the particular exception.
+   * @param code an error code from the given exception.
+   * @return the message ID.
+   */
+  private String getMessageID(String groupName, String exceptionName, int code) {
+    if (groupName.equals("OMG"))
+      return getStandardMessageID(exceptionName, code);
+    else
+      return getSunMessageID(groupName, exceptionName, code);
+  }
+
+  /**
+   * Returns the standard (OMG) message ID corresponding to the given
+   * exception name and error code.
+   *
+   * @param exceptionName the name of the particular exception.
+   * @param code an error code from the given exception.
+   * @return the message ID.
+   */
+  private String getStandardMessageID(String exceptionName, int code) {
+    return new Formatter().format("IOP%s0%04d", getExceptionID(exceptionName),
+				  code).toString();
+  }
+
+  /**
+   * Returns the Sun message ID corresponding to the given group name,
+   * exception name and error code.
+   *
+   * @param groupName the name of the group of exceptions.
+   * @param exceptionName the name of the particular exception.
+   * @param code an error code from the given exception.
+   * @return the message ID.
+   */
+  private String getSunMessageID(String groupName, String exceptionName, int code) {
+    return new Formatter().format("IOP%s1%04d", getExceptionID(exceptionName),
+				  getSunBaseNumber(groupName) + code).toString();
+  }
+
+  /**
+   * Returns the exception ID corresponding to the given exception name.
+   *
+   * @param exceptionName the name of the particular exception.
+   * @return the message ID.
+   */
+  private String getExceptionID(String exceptionName) {
+    return new Formatter().format("%03d", EXCEPTIONS.indexOf(exceptionName)).toString();
+  }
+      
+  /**
+   * Entry point for running the generator from the command
+   * line.  Users can specify either "make-class" or "make-resource"
+   * as the first argument to generate the specified type of file.
+   *
+   * @param args the command-line arguments.
+   * @throws FileNotFoundException if the input file can not be found.
+   * @throws IOException if an I/O error occurs.
+   */
+  public static void main(String[] args)
+    throws FileNotFoundException, IOException
+  {
+    if (args.length < 3)
+      {
+	System.err.println("(make-class|make-resource) <input file> <output dir>");
+	System.exit(-1);
+      }
+    if (args[0].equals("make-class"))
+      new MC().makeClass(args[1], args[2]);
+    else if (args[0].equals("make-resource"))
+      new MC().makeResource(args[1], args[2]);
+    else
+      System.err.println("Invalid command: " + args[0]);
+  }
+
+}
Binary file corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jscheme.jar has changed
Binary file corba/src/share/classes/com/sun/tools/corba/se/logutil/lib/jschemelogutil.jar has changed
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-#! /bin/sh
-java -cp lib/jscheme.jar:lib/util.jar jscheme.REPL mc.scm -main main $@
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/mc.scm	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,662 +0,0 @@
-; Scheme program to produce CORBA standard exceptions class
-; requires Jscheme Java extensions
-; Makes use of some custom Java classes also
-
-(import "com.sun.tools.corba.se.logutil.IndentingPrintWriter" ) 
-(import "com.sun.tools.corba.se.logutil.StringUtil" ) 
-(import "java.io.FileOutputStream")
-
-(define version-string "1.3")
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Utility functions
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; reload this file (convenience definition)
-(define (reload) (load "mc.scm"))
-
-; Simple little function to report an error
-(define (error msg)
-    (throw (Error. msg)))
-
-; some debug support
-(define debug #f)
-
-(define (dprint msg)
-    (if debug
-	(.println System.out$ msg)))
-
-; Replace dprint with noprint to avoid seeing messages when debug is #t
-(define (noprint msg) ())
-
-; Helper function present so that a scheme method taking strings as args 
-; can be easily run from a command line.
-; arg:	    vector containing argument strings. Element 0 is the function name
-;	    to execute
-(define (main arg)
-    (let*
-	(
-	    (arg-list (vector->list arg))
-	    (function-symbol (string->symbol (car arg-list)))
-	    (args (cdr arg-list)))
-	(apply (eval function-symbol) args)))
-
-; Returns the position of key in lst, numbering from 0.  key is matched using eqv?
-(define (get-list-position key lst)
-    (letrec
-	(
-	    (helper (lambda (k l accum)
-		(cond 
-		    ((null? l) (error (string-append "Could not find " k)))
-		    ((eqv? k (car l)) accum)
-		    (else (helper k (cdr l) (+ accum 1))) ))))
-	(begin 
-	    (noprint (string-append "get-list-position called with key " key " lst " lst ))
-	    (helper key lst 0))))
-
-; Return a string representing number in decimal padded to length with leading 0s.
-(define (pad-number-string number length)
-    (let*
-	(
-	    (number-string (number->string number))
-	    (pad-length (- length (string-length number-string)))
-	)
-	(string-append (make-string pad-length #\0) number-string)))
-
-; Read an S-expression from a file that contains all of the data.
-;
-; The S-expression used for minor codes must have the structure
-;   (package-name class-name exception-group-name
-;	(exception
-;	    (name value level explanation)
-;	    ...
-;	)
-;	...
-;   )
-(define (read-file fname)
-    (read (open-input-file fname)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Functions for handling major system exceptions and exception groups
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; Function to find the base ID given an exception group name.  Result is a function that
-; maps the minor code into the Java expression for that minor code's actual value.
-(define (get-base group-name)
-	(if (eqv? group-name 'OMG)
-	    (lambda (minor-code)
-		(string-append "OMGVMCID.value + " (number->string minor-code)))
-	    (let  ; bind base-number outside the lambda so it is only evaluated once
-		(
-		    (base-number (get-sun-base-number group-name)))
-		(lambda (minor-code)
-		    (string-append "SUNVMCID.value + " (number->string (+ base-number minor-code)))))))
-
-; Function to get a base value for the group-name
-(define (get-sun-base-number group-name)
-    (let*
-	(
-	    (lst (list 'SUNBASE 'ORBUTIL 'ACTIVATION 'NAMING 'INTERCEPTORS 'POA 'IOR 'UTIL))
-	    (subsystem-size 200))
-	(* subsystem-size (get-list-position group-name lst))))
-
-; Function to get a 3 digit number for a system exception
-(define (get-exception-id exception-name)
-    (let
-	(
-	    (lst (list 'UNKNOWN 'BAD_PARAM 'NO_MEMORY 'IMP_LIMIT 'COMM_FAILURE 'INV_OBJREF 'NO_PERMISSION 
-		'INTERNAL 'MARSHAL 'INITIALIZE 'NO_IMPLEMENT 'BAD_TYPECODE 'BAD_OPERATION 'NO_RESOURCES 
-		'NO_RESPONSE 'PERSIST_STORE 'BAD_INV_ORDER 'TRANSIENT 'FREE_MEM 'INV_IDENT 'INV_FLAG 
-		'INTF_REPOS 'BAD_CONTEXT 'OBJ_ADAPTER 'DATA_CONVERSION 'OBJECT_NOT_EXIST 'TRANSACTION_REQUIRED 
-		'TRANSACTION_ROLLEDBACK 'INVALID_TRANSACTION 'INV_POLICY 'CODESET_INCOMPATIBLE 'REBIND 
-		'TIMEOUT 'TRANSACTION_UNAVAILABLE 'BAD_QOS 'INVALID_ACTIVITY 'ACTIVITY_COMPLETED 
-		'ACTIVITY_REQUIRED )))
-	(pad-number-string (get-list-position exception-name lst) 3)))
-
-; Return the message id string for any system exception
-;
-(define (get-message-id exception-type group-name minor)
-    (if (eqv? group-name 'OMG)
-	(get-standard-message-id exception-type minor)
-	(get-sun-message-id exception-type group-name minor)))
-
-; Return the message id string for a particular standard exception
-;
-(define (get-standard-message-id exception-type minor)
-    (string-append 
-	"IOP" 
-	(get-exception-id exception-type) 
-	"0" 
-	(pad-number-string (number->string minor) 4)))
-
-; Return the sun message id for this exception-type, group-name, and minor code.
-(define (get-sun-message-id exception-type group-name minor)
-    (string-append 
-	"IOP" 
-	(get-exception-id exception-type) 
-	"1"
-	(pad-number-string (+ (get-sun-base-number group-name) minor) 4)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-; visitor framework for the input file format
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(define (visit-top obj func1)
-    (let*
-	(
-	    (package (car obj))
-	    (class (cadr obj))
-	    (group (caddr obj))
-	    (func2 (func1 package class group))
-	    (exceptions (cadddr obj)))
-	(visit-exceptions exceptions func2)))
-
-; visit the elements of an arbitrary list
-; lst:		the list to visit
-; func:		the function to apply to each element of lst
-; next-level	the function on lst element and func that visits the next level
-(define (visit-list lst func next-level)
-    (if (null? (cdr lst))
-	(next-level #t (car lst) func)
-	(begin
-	    (next-level #f (car lst) func)
-	    (visit-list (cdr lst) func next-level))))
-
-(define (visit-exceptions exceptions func2)
-    (visit-list exceptions func2 (lambda (last-flag element func) (visit-exception last-flag element func))))
-
-(define (visit-exception last-flag exception func2)
-    (let*
-	(
-	    (major (car exception))
-	    (minor-codes (cdr exception))
-	    (func3 (func2 last-flag major)))
-	(visit-minor-codes minor-codes func3)))
-
-(define (visit-minor-codes minor-codes func3)
-    (visit-list minor-codes func3 (lambda (last-flag element func) (visit-minor-code last-flag element func))))
-
-(define (visit-minor-code last-flag minor-code func3)
-    (let*   
-	(
-	    (name (car minor-code))
-	    (minor (cadr minor-code))
-	    (level (caddr minor-code))
-	    (msg (cadddr minor-code)))
-	(func3 last-flag name minor level msg)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; The visitors
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; A simple visitor that just echoes the input for test purposes
-(define (simple-visitor package class group)
-    (let* 
-	(
-	    (pw (IndentingPrintWriter. System.out$)))
-	(begin
-	    (.indent pw)
-	    (.printMsg pw "package=@ class=@ group=@" (list package class group))
-	    (.flush pw)
-	    (lambda (last-flag major)
-		(begin
-		    (.indent pw)
-		    (.printMsg pw "major=@" (list major))
-		    (.flush pw)
-		    (lambda (last-flag name minor level message)
-			(begin
-			    (if last-flag (.undent pw))
-			    (.printMsg pw "name=@ minor=@ level=@ message=@" (list name minor level message))
-			    (.flush pw))))))))
-
-; Function that returns a visitor that writes out the resource file in the form:
-;   id="MSGID: explanation"
-; outdir: Output directory 
-(define (resource-visitor outdir)
-    (lambda (package class group)
-	(let* 
-	    (
-		(file-name (string-append outdir java.io.File.separator$ class ".resource"))
-		(pw (IndentingPrintWriter. (FileOutputStream. file-name))))
-	    (begin 
-		(dprint (string-append "package= " package " class=" class " group=" group " file-name=" file-name))
-		(lambda (last-flag1 major)
-		    (begin
-			; (dprint (string-append "last-flag1=" last-flag1 " major=" major))
-			(lambda (last-flag2 name minor level message)
-			    (begin
-				; (dprint (string-append "last-flag2=" last-flag2 " name=" name 
-				    ; " minor=" minor " level=" level " message=" message))
-				(let*
-				    (
-					(msgid (get-message-id major group minor))
-					(ident (StringUtil.toMixedCase (symbol->string name))))
-				    (begin
-					; (dprint (string-append "msgid=" msgid " ident=" ident))
-					(.printMsg pw "@.@=\"@: (@) @\"" (list group ident msgid major message))
-					(.flush pw)
-					(if (and last-flag1 last-flag2) 
-					    (begin
-						; (dprint "closing file")
-						(.close pw)))))))))))))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Top-level functions for creating the products.  All have names of the form make-xxx
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; Read the minor codes from the infile and write out a resource file. 
-(define (make-resource infile outdir)
-    (tryCatch 
-	(visit-top (read-file infile) (resource-visitor outdir))
-	(lambda (exc) 
-	    (begin
-		(.println System.out$ (string-append "make-resource failed with exception " (.toString exc)))
-		(System.exit 1)))))
-
-; Read the minor codes from the infile and write a Java implementation to
-; handle them to outfile under outdir
-(define (make-class infile outdir)
-    (tryCatch 
-	(write-class infile outdir (read-file infile))
-	(lambda (exc) 
-	    (begin
-		(.println System.out$ (string-append "make-class failed with exception " (.toString exc)))
-		(System.exit 1)))))
-	
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; The original make-class implementation (this should be replaced by two visitors)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; Write out the Java source code for the StandardExceptions class
-; outdir:  Output directory to write the generated files
-; obj:	    the data from the input file
-(define (write-class infile outdir obj)
-    (let* 
-	( 
-	    (package-name (car obj))
-	    (class-name (cadr obj))
-	    (exception-group-name (caddr obj))
-	    (exceptions (cadddr obj))
-	    (file (FileOutputStream. (string-append outdir java.io.File.separator$  class-name ".java")))  
-	    (pw   (IndentingPrintWriter. file))
-	)
-	(begin
-	    (write-class-header infile package-name class-name exception-group-name pw)
-	    (.printMsg pw "package @ ;"
-		(list package-name))
-	    (.println pw)
-	    (.println pw "import java.util.logging.Logger ;")
-	    (.println pw "import java.util.logging.Level ;")
-	    (.println pw)
-	    (.println pw "import org.omg.CORBA.OMGVMCID ;")
-	    (.println pw "import com.sun.corba.se.impl.util.SUNVMCID ;")
-	    (.println pw "import org.omg.CORBA.CompletionStatus ;")
-	    (.println pw "import org.omg.CORBA.SystemException ;")
-	    (.println pw)
-	    (.println pw "import com.sun.corba.se.spi.orb.ORB ;")
-	    (.println pw)
-	    (.println pw "import com.sun.corba.se.spi.logging.LogWrapperFactory;")
-	    (.println pw)
-	    (.println pw "import com.sun.corba.se.spi.logging.LogWrapperBase;")
-	    (.println pw)
-	    (write-imports exceptions pw)
-	    (.println pw)
-	    (.indent pw)
-	    (.printMsg pw "public class @ extends LogWrapperBase {"
-		(list class-name))
-	    (.println pw)
-	    (.printMsg pw "public @( Logger logger )"
-		(list class-name))
-	    (.indent pw)
-	    (.println pw "{")
-	    (.undent pw)
-	    (.println pw "super( logger ) ;")
-	    (.println pw "}")
-	    (.println pw)
-	    (.flush pw)
-	    (write-factory-method class-name exception-group-name pw)
-	    (write-exceptions exception-group-name exceptions (get-base exception-group-name) class-name pw)
-	    (.undent pw)
-	    (.println pw )
-	    (.println pw "}")
-	    (.flush pw)
-	    (.close pw)
-	)))
-
-; Write out the header for the resource file
-(define (write-class-header infile package class group pw)
-    (begin
-	(if (eqv? group 'OMG)
-	    (.println pw "// Log wrapper class for standard exceptions")
-	    (.printMsg pw "// Log wrapper class for Sun private system exceptions in group @" (list group)))
-	(.println pw "//")
-	(.printMsg pw "// Generated by mc.scm version @, DO NOT EDIT BY HAND!" (list version-string))
-	(.printMsg pw "// Generated from input file @ on @" (list infile (java.util.Date.)))
-	(.println pw)))
-
-(define (write-factory-method class-name exception-group-name pw)
-    (begin
-	(.indent pw)
-	(.println pw "private static LogWrapperFactory factory = new LogWrapperFactory() {")
-	(.println pw "public LogWrapperBase create( Logger logger )" )
-	(.indent pw)
-	(.println pw "{")
-	(.undent pw)
-	(.printMsg pw "return new @( logger ) ;" (list class-name))
-	(.undent pw)
-	(.println pw "}" )
-	(.println pw "} ;" )
-	(.println pw)
-	(.printMsg pw "public static @ get( ORB orb, String logDomain )" (list class-name))
-	(.indent pw)	
-	(.println pw "{")
-	(.indent pw)	
-	(.printMsg pw "@ wrapper = "
-	    (list class-name))
-	(.indent pw)
-	(.printMsg pw "(@) orb.getLogWrapper( logDomain, " 
-	    (list class-name))
-	(.undent pw)	
-	(.undent pw)	
-	(.printMsg pw "\"@\", factory ) ;" 
-	    (list exception-group-name))
-	(.undent pw)	
-	(.println pw "return wrapper ;" )
-	(.println pw "} " )
-	(.println pw)
-	(.printMsg pw "public static @ get( String logDomain )" (list class-name))
-	(.indent pw)	
-	(.println pw "{")
-	(.indent pw)	
-	(.printMsg pw "@ wrapper = "
-	    (list class-name))
-	(.indent pw)
-	(.printMsg pw "(@) ORB.staticGetLogWrapper( logDomain, " 
-	    (list class-name))
-	(.undent pw)	
-	(.undent pw)	
-	(.printMsg pw "\"@\", factory ) ;" 
-	    (list exception-group-name))
-	(.undent pw)	
-	(.println pw "return wrapper ;" )
-	(.println pw "} " )
-	(.println pw)))
-
-; Write out the import list for the exceptions listed in obj
-; obj:	    the data from the input file
-; pw:	    an IndentingPrintWriter for the output file
-(define (write-imports obj pw)
-    (if (null? obj)
-	()
-	(let 
-	    (
-		(exception (caar obj))
-	    )
-	    (begin
-		(.print pw "import org.omg.CORBA.")
-		(.print pw exception)
-		(.println pw " ;")
-		(write-imports (cdr obj) pw)
-	    ))))
-
-; Write out the list of exceptions starting with the first one
-; obj:	    the data from the input file
-; base:	    the lambda that returns the string defining the minor code value
-; pw:	    an IndentingPrintWriter for the output file
-(define (write-exceptions group-name obj base class-name pw)
-    (if (null? obj) 
-	()
-	(let* 
-	    (
-		(record (car obj))
-		(exception (car record))
-	        (minor-codes (cdr record))
-	    )
-	    (begin
-		(write-exception group-name exception minor-codes base class-name pw)
-		(write-exceptions group-name (cdr obj) base class-name pw)
-	    ))))
-
-; Write out a single exception
-; exception:	the CORBA SystemException type
-; base:		the base for the minor code value
-; minor-codes:	a list of minor code data for each minor exception type
-; pw:		an IndentingPrintWriter for the output file
-(define (write-exception group-name exception minor-codes base class-name pw)
-    (begin
-	(.println pw "///////////////////////////////////////////////////////////")
-	(.printMsg pw "// @" (list exception))
-	(.println pw "///////////////////////////////////////////////////////////")
-	(.println pw)
-	(write-methods group-name exception minor-codes base class-name pw)
-	(.flush pw)))
-
-; Write all of the methods for a single exception
-; exception:	the CORBA SystemException type
-; base:		the base for the minor code value
-; minor-codes:	a list of minor code data for each minor exception type
-; pw:		an IndentingPrintWriter for the output file
-(define (write-methods group-name exception minor-codes base class-name pw)
-    (if (null? minor-codes)
-	()
-	(begin
-	    (write-method group-name exception (car minor-codes) base class-name pw)
-	    (write-methods group-name exception (cdr minor-codes) base class-name pw)
-	)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Code that writes out the Java methods for exception handling
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-; Write the methods for a single minor code within an exception
-; exception:	the CORBA SystemException type
-; minor-code:	minor code data for one minor exception type 
-;		(name value level explanation)
-; base:		the base for the minor code value
-; pw:		an IndentingPrintWriter for the output file
-(define (write-method group-name exception minor-code base class-name pw)
-    (let* 
-	(
-	    (x (symbol->string (car minor-code)))
-	    (ident (cons x (StringUtil.toMixedCase x)))
-	    (value (cadr minor-code))
-	    (level (symbol->string (caddr minor-code)))
-	    (explanation (cadddr minor-code))
-	    (num-params (StringUtil.countArgs explanation)))
-	(begin
-	    (.printMsg pw "public static final int @ = @ ;"
-		(list x (base value)))
-	    (.println pw )
-	    (.flush pw )
-	    (write-method-status-cause group-name exception ident level num-params class-name pw)
-	    (.println pw)
-	    (.flush pw)
-	    (write-method-status exception ident level num-params pw)
-	    (.println pw)
-	    (.flush pw)
-	    (write-method-cause exception ident level num-params pw)
-	    (.println pw)
-	    (.flush pw)
-	    (write-method-no-args exception ident level num-params pw)
-	    (.println pw)
-	    (.flush pw))))
-
-; Construct a string of the form arg1, ..., argn where n is num-params
-(define (make-arg-string fixed leading-comma-flag num-args)
-    (let
-	(
-	    (helper (lambda (lcf n)
-		(let*
-		    (
-			(numstr (number->string (- n 1))))
-		    (if (or lcf (> n 1))
-			(string-append ", " fixed numstr)
-			(string-append " " fixed numstr))))))
-	(cond 
-	    ((eqv? num-args 0) " ")
-	    ((eqv? num-args 1) (helper leading-comma-flag 1))
-	    (else (string-append 
-		(make-arg-string fixed leading-comma-flag (- num-args 1)) 
-		(helper leading-comma-flag num-args ))))))
-
-(define (make-decl-args leading-comma-flag num-args)
-    (make-arg-string "Object arg" leading-comma-flag num-args))
-
-(define (make-call-args leading-comma-flag num-args)
-    (make-arg-string "arg" leading-comma-flag num-args))
-
-; make-xxx-args patterns:
-; leading-comma-flag #t
-;
-;   0   " "
-;   1   ", arg0"
-;   2   ", arg0, arg1"
-;   3   ", arg0, arg1, arg2"
-;
-;   0   " "
-;   1   ", Object arg0"
-;   2   ", Object arg0, Object arg1"
-;   3   ", Object arg0, Object arg1, Object arg2"
-;
-; leading-comma-flag #f
-;
-;   0   " "
-;   1   " arg0"
-;   2   " arg0, arg1"
-;   3   " arg0, arg1, arg2"
-;
-;   0   " "
-;   1   " Object arg0"
-;   2   " Object arg0, Object arg1"
-;   3   " Object arg0, Object arg1, Object arg2"
-
-(define (emit-assignments num pw)
-    (let 
-	(
-	    (helper 
-		(lambda (n) 
-		    (.printMsg pw "parameters[@] = arg@ ;" (list n n)))))
-	(if (= num 1)
-	    (helper (- num 1))
-	    (begin
-		(emit-assignments (- num 1) pw)
-		(helper (- num 1))))))
-
-; Write a method for an exception that takes a CompletionStatus and a cause
-; exception:	the CORBA system exception type
-; id:		the identifier for this exception in the form ( ident . mixed-case-ident )
-; level:	the logging level
-; num-params:	number of parameters in the explanation string, which determines
-;		how many argn parameters we need
-; pw:		the indenting print writer we are using
-(define (write-method-status-cause group-name exception id level num-params class-name pw)
-    (let*
-	(
-	    (ident (car id))
-	    (ident-mc (cdr id)))
-    (begin
-	(.indent pw)
-	(.printMsg pw "public @ @( CompletionStatus cs, Throwable t@) {"
-	    (list exception ident-mc (make-decl-args #t num-params)))
-	(.printMsg pw "@ exc = new @( @, cs ) ;"
-	    (list exception exception ident ))
-
-	(.indent pw)
-	(.println pw "if (t != null)" )
-	(.undent pw)
-	(.println pw "exc.initCause( t ) ;" )	
-	(.println pw)
-
-	(.indent pw)
-	(.printMsg pw "if (logger.isLoggable( Level.@ )) {"
-	    (list level))
-	
-	(if (> num-params 0)
-	    (begin
-		(.printMsg pw "Object[] parameters = new Object[@] ;"
-		    (list (number->string num-params)))
-		(emit-assignments num-params pw)
-	    )
-	    (begin
-		(.println pw "Object[] parameters = null ;"
-	    )))
-
-	(.indent pw)
-	(.printMsg pw "doLog( Level.@, \"@.@\"," (list level group-name ident-mc))
-	(.undent pw)
-	(.undent pw)
-	(.printMsg pw "parameters, @.class, exc ) ;" (list class-name))
-	(.println pw "}")
-	(.println pw)
-
-	(.undent pw)
-	(.println pw "return exc ;")
-
-	(.println pw "}"))))
-
-; Write a method for an exception that takes a CompletionStatus.  The cause is null. 
-;
-; exception:	the CORBA system exception type
-; id:		the identifier for this exception in the form ( ident . mixed-case-ident )
-; level:	the logging level
-; num-params:	number of parameters in the explanation string, which determines
-;		how many argn parameters we need
-; pw:		the indenting print writer we are using
-(define (write-method-status exception id level num-params pw)
-    (let*
-	(
-	    (ident-mc (cdr id)))
-	(begin
-	    (.indent pw)
-	    (.printMsg pw "public @ @( CompletionStatus cs@) {"
-		(list exception ident-mc (make-decl-args #t num-params)))
-	    (.undent pw)
-	    (.printMsg pw "return @( cs, null@ ) ;"
-		(list ident-mc (make-call-args #t num-params)))
-	    (.println pw "}"))))
-
-; Write a method for an exception that takes a cause.  The status is COMPLETED_NO. 
-;
-; exception:	the CORBA system exception type
-; id:		the identifier for this exception in the form ( ident . mixed-case-ident )
-; level:	the logging level
-; num-params:	number of parameters in the explanation string, which determines
-;		how many argn parameters we need
-; pw:		the indenting print writer we are using
-(define (write-method-cause exception id level num-params pw)
-    (let*
-	(
-	    (ident-mc (cdr id)))
-	(begin
-	    (.indent pw)
-	    (.printMsg pw "public @ @( Throwable t@) {"
-		(list exception ident-mc (make-decl-args #t num-params)))
-	    (.undent pw)
-	    (.printMsg pw "return @( CompletionStatus.COMPLETED_NO, t@ ) ;"
-		(list ident-mc (make-call-args #t num-params)))
-	    (.println pw "}"))))
-
-; Write a method for an exception that takes no arguments.  This is COMPLETED_NO and
-; a null cause.
-;
-; exception:	the CORBA system exception type
-; id:		the identifier for this exception in the form ( ident . mixed-case-ident )
-; level:	the logging level
-; num-params:	number of parameters in the explanation string, which determines
-;		how many argn parameters we need
-; pw:		the indenting print writer we are using
-(define (write-method-no-args exception id level num-params pw)
-    (let*
-	(
-	    (ident-mc (cdr id)))
-	(begin
-	    (.indent pw)
-	    (.printMsg pw "public @ @( @) {"
-		(list exception ident-mc (make-decl-args #f num-params)))
-	    (.undent pw)
-	    (.printMsg pw "return @( CompletionStatus.COMPLETED_NO, null@ ) ;"
-		(list ident-mc (make-call-args #t num-params)))
-	    (.println pw "}"))))
-
-;;; end of file
--- a/corba/src/share/classes/com/sun/tools/corba/se/logutil/scripts/run	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-#! /bin/sh
-java -cp ${CLASSPATH}:lib/jscheme.jar:lib/util.jar jscheme.REPL mc.scm
Binary file hotspot/agent/kk/src/share/lib/jlfgr-1_0.jar has changed
Binary file hotspot/agent/kk/src/share/lib/maf-1_0.jar has changed
Binary file hotspot/build/linux/Queens.class has changed
--- a/hotspot/build/linux/makefiles/buildtree.make	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/build/linux/makefiles/buildtree.make	Thu Jul 10 00:00:00 2008 +0200
@@ -284,7 +284,7 @@
 WRONG_DATA_MODE_MSG = \
 	echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
 
-test_gamma:  $(BUILDTREE_MAKE)
+test_gamma:  $(BUILDTREE_MAKE) Queens.class
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	echo '#!/bin/sh'; \
@@ -295,12 +295,17 @@
 	echo "then"; \
 	echo "  $(WRONG_DATA_MODE_MSG); exit 0;"; \
 	echo "fi"; \
-	echo 'CLASSPATH="$(GAMMADIR)/build/$(OS_FAMILY):$$CLASSPATH"'; \
 	echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
 	echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
 	) > $@
 	$(QUIETLY) chmod +x $@
 
+include $(GAMMADIR)/build/linux/makefiles/rules.make
+
+Queens.class: $(GAMMADIR)/build/test/Queens.java
+	$(RM) -f $@
+	$(REMOTE) $(COMPILE.JAVAC) -d . $<
+
 FORCE:
 
 .PHONY:  all FORCE
Binary file hotspot/build/solaris/Queens.class has changed
--- a/hotspot/build/solaris/makefiles/buildtree.make	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/build/solaris/makefiles/buildtree.make	Thu Jul 10 00:00:00 2008 +0200
@@ -299,7 +299,7 @@
 WRONG_DATA_MODE_MSG = \
 	echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
 
-test_gamma:  $(BUILDTREE_MAKE)
+test_gamma:  $(BUILDTREE_MAKE) Queens.class
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	echo '#!/bin/ksh'; \
@@ -310,12 +310,17 @@
 	echo "then"; \
 	echo "  $(WRONG_DATA_MODE_MSG); exit 0;"; \
 	echo "fi"; \
-	echo 'CLASSPATH="$(GAMMADIR)/build/$(OS_FAMILY):$$CLASSPATH"'; \
 	echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
 	echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
 	) > $@
 	$(QUIETLY) chmod +x $@
 
+include $(GAMMADIR)/build/solaris/makefiles/rules.make
+
+Queens.class: $(GAMMADIR)/build/test/Queens.java
+	$(RM) -f $@
+	$(REMOTE) $(COMPILE.JAVAC) -d . $<
+
 FORCE:
 
 .PHONY:  all FORCE
--- a/hotspot/src/os/linux/vm/jvm_linux.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/os/linux/vm/jvm_linux.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)jvm_linux.cpp	1.21 07/05/05 17:04:36 JVM"
+#pragma ident "@(#)jvm_linux.cpp	1.22 08/06/16 14:15:16 JVM"
 #endif
 /*
  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -135,7 +135,7 @@
 */
 
 struct siglabel {
-  char *name;
+  const char *name;
   int   number;
 };
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)os_linux.cpp	1.257 07/05/17 15:48:43 JVM"
+#pragma ident "@(#)os_linux.cpp	1.258 08/06/16 14:16:05 JVM"
 #endif
 /*
  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -78,8 +78,8 @@
 bool os::Linux::_is_floating_stack = false;
 bool os::Linux::_is_NPTL = false;
 bool os::Linux::_supports_fast_thread_cpu_time = false;
-char * os::Linux::_glibc_version = NULL;
-char * os::Linux::_libpthread_version = NULL;
+const char * os::Linux::_glibc_version = NULL;
+const char * os::Linux::_libpthread_version = NULL;
 
 static jlong initial_time_count=0;
 
@@ -202,9 +202,9 @@
 // the system call returns 1.  This causes the VM to act as if it is
 // a single processor and elide locking (see is_MP() call).
 static bool unsafe_chroot_detected = false;
-static char *unstable_chroot_error = "/proc file system not found.\n"
-              "Java may be unstable running multithreaded in a chroot "
-              "environment on Linux when /proc filesystem is not mounted.";
+static const char *unstable_chroot_error = "/proc file system not found.\n"
+                    "Java may be unstable running multithreaded in a chroot "
+                    "environment on Linux when /proc filesystem is not mounted.";
 
 void os::Linux::initialize_system_info() {
   _processor_count = sysconf(_SC_NPROCESSORS_CONF);
@@ -536,35 +536,33 @@
 
      // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
      // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
-     // is the case:
+     // is the case. Also, LinuxThreads has a hard limit on max number of 
+     // threads. So sysconf(_SC_THREAD_THREADS_MAX) will return a positive 
+     // value.On the other hand, NPTL does not have such a limit, sysconf()
+     // will return -1 and errno is not changed. Check if it is really NPTL.
      if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
-         strstr(str, "NPTL")) {
-        // LinuxThreads has a hard limit on max number of threads. So
-        // sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
-        // On the other hand, NPTL does not have such a limit, sysconf()
-        // will return -1 and errno is not changed. Check if it is really
-        // NPTL:
-        if (sysconf(_SC_THREAD_THREADS_MAX) > 0) {
-           free(str);
-           str = "linuxthreads";
-        }
+         strstr(str, "NPTL") &&
+         sysconf(_SC_THREAD_THREADS_MAX) > 0) {
+       free(str);
+       os::Linux::set_libpthread_version("linuxthreads");
+     } else {
+       os::Linux::set_libpthread_version(str);
      }
-     os::Linux::set_libpthread_version(str);
   } else {
-     // glibc before 2.3.2 only has LinuxThreads.
-     os::Linux::set_libpthread_version("linuxthreads");
+    // glibc before 2.3.2 only has LinuxThreads.
+    os::Linux::set_libpthread_version("linuxthreads");
   }
-
+  
   if (strstr(libpthread_version(), "NPTL")) {
-     os::Linux::set_is_NPTL();
+    os::Linux::set_is_NPTL();
   } else {
-     os::Linux::set_is_LinuxThreads();
+    os::Linux::set_is_LinuxThreads();
   }
-
+  
   // LinuxThreads have two flavors: floating-stack mode, which allows variable 
   // stack size; and fixed-stack mode. NPTL is always floating-stack.
   if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
-     os::Linux::set_is_floating_stack();
+    os::Linux::set_is_floating_stack();
   }
 }
 
--- a/hotspot/src/os/linux/vm/os_linux.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)os_linux.hpp	1.70 07/05/05 17:04:37 JVM"
+#pragma ident "@(#)os_linux.hpp	1.71 08/06/16 14:16:05 JVM"
 #endif
 /*
  * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -55,8 +55,8 @@
   static address   _initial_thread_stack_bottom;
   static uintptr_t _initial_thread_stack_size;
 
-  static char *_glibc_version;
-  static char *_libpthread_version;
+  static const char *_glibc_version;
+  static const char *_libpthread_version;
 
   static bool _is_floating_stack;
   static bool _is_NPTL;
@@ -73,8 +73,8 @@
   static julong physical_memory() { return _physical_memory; }
   static void initialize_system_info();
 
-  static void set_glibc_version(char *s)      { _glibc_version = s; }
-  static void set_libpthread_version(char *s) { _libpthread_version = s; }
+  static void set_glibc_version(const char *s)      { _glibc_version = s; }
+  static void set_libpthread_version(const char *s) { _libpthread_version = s; }
 
   static bool supports_variable_stack_size();
 
@@ -134,8 +134,8 @@
   static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
 
   // GNU libc and libpthread version strings
-  static char *glibc_version()                { return _glibc_version; }
-  static char *libpthread_version()           { return _libpthread_version; }
+  static const char *glibc_version()          { return _glibc_version; }
+  static const char *libpthread_version()     { return _libpthread_version; }
 
   // NPTL or LinuxThreads?
   static bool is_LinuxThreads()               { return !_is_NPTL; }
--- a/hotspot/src/os/linux/vm/vmError_linux.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/os/linux/vm/vmError_linux.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)vmError_linux.cpp	1.13 07/05/05 17:04:37 JVM"
+#pragma ident "@(#)vmError_linux.cpp	1.14 08/06/17 09:14:15 JVM"
 #endif
 /*
  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -49,11 +49,7 @@
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
 int VMError::fork_and_exec(char* cmd) {
-  char * argv[4];
-  argv[0] = "sh";
-  argv[1] = "-c";
-  argv[2] = cmd;
-  argv[3] = NULL;
+  const char * argv[4] = {"sh", "-c", cmd, NULL};
 
   // fork() in LinuxThreads/NPTL is not async-safe. It needs to run 
   // pthread_atfork handlers and reset pthread library. All we need is a 
@@ -78,7 +74,7 @@
     // IA64 should use normal execve() from glibc to match the glibc fork() 
     // above.
     NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
-    IA64_ONLY(execve("/bin/sh", argv, environ);)
+    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
 
     // execve failed
     _exit(-1);
--- a/hotspot/src/os/solaris/vm/vmError_solaris.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/os/solaris/vm/vmError_solaris.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)vmError_solaris.cpp	1.12 07/05/05 17:04:43 JVM"
+#pragma ident "@(#)vmError_solaris.cpp	1.13 08/06/17 09:14:34 JVM"
 #endif
 /*
  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -39,11 +39,7 @@
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
 int VMError::fork_and_exec(char* cmd) {
-  char * argv[4];
-  argv[0] = (char *)"sh";
-  argv[1] = (char *)"-c";
-  argv[2] = cmd;
-  argv[3] = NULL;
+  const char * argv[4] = {"sh", "-c", cmd, NULL};
 
   // fork is async-safe, fork1 is not so can't use in signal handler
   pid_t pid;
@@ -63,7 +59,7 @@
     // child process
 
     // try to be consistent with system(), which uses "/usr/bin/sh" on Solaris
-    execve("/usr/bin/sh", argv, environ);
+    execve("/usr/bin/sh", (char* const*)argv, environ);
 
     // execve failed
     _exit(-1);
--- a/hotspot/src/share/vm/adlc/archDesc.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -22,10 +22,6 @@
 //  
 //
 
-#ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)archDesc.cpp	1.273 07/05/05 17:05:01 JVM"
-#endif
-
 // archDesc.cpp - Internal format for architecture definition
 #include "adlc.hpp"
 
@@ -1029,17 +1025,11 @@
 
 //---------------------------addSUNcopyright-------------------------------
 // output SUN copyright info
-void ArchDesc::addSunCopyright(FILE *fp) {
+void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
+  fwrite(legal, size, 1, fp);
+  fprintf(fp,"\n");
   fprintf(fp,"// Machine Generated File.  Do Not Edit!\n");
   fprintf(fp,"\n");
-  fprintf(fp,"// Copyright 1997-2006 Sun Microsystems, Inc.  All rights reserved.\n");
-  fprintf(fp,"// SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.\n");
-  fprintf(fp,"// This software is the confidential and proprietary information of Sun\n");
-  fprintf(fp,"// Microsystems, Inc. (\"Confidential Information\").  You shall not\n");
-  fprintf(fp,"// disclose such Confidential Information and shall use it only in\n");
-  fprintf(fp,"// accordance with the terms of the license agreement you entered into\n");
-  fprintf(fp,"// with Sun.\n");
-  fprintf(fp,"//\n");
 }
 
 //---------------------------machineDependentIncludes--------------------------
--- a/hotspot/src/share/vm/adlc/archDesc.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/adlc/archDesc.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,6 +1,3 @@
-#ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)archDesc.hpp	1.133 07/05/05 17:04:59 JVM"
-#endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -22,7 +19,7 @@
  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  * CA 95054 USA or visit www.sun.com if you need additional information or
  * have any questions.
- *  
+ *
  */
 
 // Definitions for Error Flags
@@ -75,18 +72,18 @@
   MatchList(MatchList *nxt, Predicate *prd): _next(nxt), _pred(prd), _cost(NULL){
     _resultStr = _lchild = _rchild = _opcode = NULL; }
 
-  MatchList(MatchList *nxt, Predicate *prd, const char *cost, 
-	    const char *opcode, const char *resultStr, const char *lchild, 
-	    const char *rchild)
-    : _next(nxt), _pred(prd), _cost(cost), _opcode(opcode), 
+  MatchList(MatchList *nxt, Predicate *prd, const char *cost,
+            const char *opcode, const char *resultStr, const char *lchild,
+            const char *rchild)
+    : _next(nxt), _pred(prd), _cost(cost), _opcode(opcode),
       _resultStr(resultStr), _lchild(lchild), _rchild(rchild) { }
 
   MatchList  *get_next(void)  { return _next; }
   char       *get_pred(void)  { return (_pred?_pred->_pred:NULL); }
   Predicate  *get_pred_obj(void)  { return _pred; }
   const char *get_cost(void) { return _cost == NULL ? "0" :_cost; }
-  bool        search(const char *opc, const char *res, const char *lch, 
-		    const char *rch, Predicate *pr);
+  bool        search(const char *opc, const char *res, const char *lch,
+                    const char *rch, Predicate *pr);
 
   void        dump();
   void        output(FILE *fp);
@@ -117,17 +114,17 @@
 
   MatchList    *_mlistab[_last_opcode]; // Array of MatchLists
 
-  // The Architecture Description identifies which user-defined operand can be used 
+  // The Architecture Description identifies which user-defined operand can be used
   // to access [stack_pointer + offset]
   OperandForm  *_cisc_spill_operand;
 
   // Methods for outputting the DFA
   void gen_match(FILE *fp, MatchList &mlist, ProductionState &status, Dict &operands_chained_from);
-  void chain_rule(FILE *fp, const char *indent, const char *ideal, 
-		  const Expr *icost, const char *irule, 
+  void chain_rule(FILE *fp, const char *indent, const char *ideal,
+                  const Expr *icost, const char *irule,
                   Dict &operands_chained_from, ProductionState &status);
   void chain_rule_c(FILE *fp, char *indent, char *ideal, char *irule);  // %%%%% TODO: remove this
-  void expand_opclass(FILE *fp, const char *indent, const Expr *cost, 
+  void expand_opclass(FILE *fp, const char *indent, const Expr *cost,
                       const char *result_type, ProductionState &status);
   Expr *calc_cost(FILE *fp, const char *spaces, MatchList &mList, ProductionState &status);
   void prune_matchlist(Dict &minimize, MatchList &mlist);
@@ -150,7 +147,7 @@
   int   _adlocation_debug;              // Debug Flag to use ad file locations
   bool  _cisc_spill_debug;              // Debug Flag to see cisc-spill-instructions
   bool  _short_branch_debug;            // Debug Flag to see short branch instructions
-  
+
   // Error/Warning Counts
   int _syntax_errs;                  // Count of syntax errors
   int _semantic_errs;                // Count of semantic errors
@@ -225,8 +222,8 @@
   // Helper utility that gets MatchList components from inside MatchRule
   void check_optype(MatchRule *mrule);
   void build_chain_rule(OperandForm *oper);
-  void add_chain_rule_entry(const char *src, const char *cost, 
-			    const char *result);
+  void add_chain_rule_entry(const char *src, const char *cost,
+                            const char *result);
   const char *getMatchListIndex(MatchRule &mrule);
   void generateMatchLists();         // Build MatchList array and populate it
   void inspectOperands();            // Build MatchLists for all operands
@@ -273,10 +270,10 @@
   void build_map(OutputMap &map);
   void buildReduceMaps(FILE *fp_hpp, FILE *fp_cpp);
   // build flags for signaling that our machine needs this instruction cloned
-  void buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp); 
+  void buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp);
 
   // output SUN copyright info
-  void addSunCopyright(FILE *fp);
+  void addSunCopyright(char* legal, int size, FILE *fp);
   // output #include declarations for machine specific files
   void machineDependentIncludes(ADLFILE &adlfile);
   // Output C preprocessor code to verify the backend compilation environment.
@@ -309,7 +306,7 @@
 
   // Methods to construct the MachNode class hierarchy
   // Return the type signature for the ideal operation
-  const char *getIdealType(const char *idealOp); 
+  const char *getIdealType(const char *idealOp);
   // Declare and define the classes derived from MachOper and MachNode
   void declareClasses(FILE *fp_hpp);
   void defineClasses(FILE *fp_cpp);
@@ -317,7 +314,7 @@
   // Emit an ADLC message
   void internal_err( const char *fmt, ...);
   void syntax_err  ( int lineno, const char *fmt, ...);
-  int  emit_msg(int quiet, int flag, int linenum, const char *fmt, 
+  int  emit_msg(int quiet, int flag, int linenum, const char *fmt,
        va_list args);
 
   // Generator for has_match_rule methods
@@ -338,10 +335,10 @@
 
 protected:
   // build MatchList from MatchRule
-  void buildMatchList(MatchRule *mrule, const char *resultStr, 
-		      const char *rootOp, Predicate *pred, const char *cost);
+  void buildMatchList(MatchRule *mrule, const char *resultStr,
+                      const char *rootOp, Predicate *pred, const char *cost);
 
-  void buildMList(MatchNode *node, const char *rootOp, const char *resultOp, 
+  void buildMList(MatchNode *node, const char *rootOp, const char *resultOp,
                   Predicate *pred, const char *cost);
 
   friend class ADLParser;
@@ -361,16 +358,16 @@
   FormDict &_globals;
   ArchDesc &_AD;
 public:
-  OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD) 
+  OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD)
     : _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD) {};
   // Access files used by this routine
   FILE        *decl_file() { return _hpp; }
   FILE        *def_file()  { return _cpp; }
   // Positions in iteration that derived class will be told about
-  enum position { BEGIN_OPERANDS, 
+  enum position { BEGIN_OPERANDS,
                   BEGIN_OPCLASSES,
                   BEGIN_INTERNALS,
-                  BEGIN_INSTRUCTIONS, 
+                  BEGIN_INSTRUCTIONS,
                   BEGIN_INST_CHAIN_RULES,
                   END_INST_CHAIN_RULES,
                   BEGIN_REMATERIALIZE,
@@ -390,5 +387,3 @@
   // Allow derived class to output name and position specific info
   virtual void record_position(OutputMap::position place, int index) {}
 };
-
-
--- a/hotspot/src/share/vm/adlc/main.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/adlc/main.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,6 +1,3 @@
-#ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)main.cpp	1.100 07/05/05 17:05:01 JVM"
-#endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -33,6 +30,7 @@
 static char *strip_ext(char *fname);       // Strip off name extension
 static char *base_plus_suffix(const char* base, const char *suffix);// New concatenated string 
 static char *prefix_plus_base_plus_suffix(const char* prefix, const char* base, const char *suffix);// New concatenated string 
+static int get_legal_text(FileBuff &fbuf, char **legal_text); // Get pointer to legal text
 
 ArchDesc* globalAD = NULL;      // global reference to Architecture Description object
 
@@ -161,6 +159,11 @@
   // Build the File Buffer, Parse the input, & Generate Code
   FileBuff  ADL_Buf(&AD._ADL_file, AD); // Create a file buffer for input file
 
+  // Get pointer to legal text at the beginning of AD file.
+  // It will be used in generated ad files.
+  char* legal_text;
+  int legal_sz = get_legal_text(ADL_Buf, &legal_text);
+
   ADL_Parse = new ADLParser(ADL_Buf, AD); // Create a parser to parse the buffer
   ADL_Parse->parse();           // Parse buffer & build description lists
 
@@ -179,15 +182,17 @@
   AD.identify_cisc_spill_instructions();
   AD.identify_short_branches();
   // Make sure every file starts with a copyright:
-  AD.addSunCopyright(AD._HPP_file._fp);           // .hpp
-  AD.addSunCopyright(AD._CPP_file._fp);           // .cpp
-  AD.addSunCopyright(AD._CPP_CLONE_file._fp);     // .cpp
-  AD.addSunCopyright(AD._CPP_EXPAND_file._fp);    // .cpp
-  AD.addSunCopyright(AD._CPP_FORMAT_file._fp);    // .cpp
-  AD.addSunCopyright(AD._CPP_GEN_file._fp);       // .cpp
-  AD.addSunCopyright(AD._CPP_MISC_file._fp);      // .cpp
-  AD.addSunCopyright(AD._CPP_PEEPHOLE_file._fp);  // .cpp
-  AD.addSunCopyright(AD._CPP_PIPELINE_file._fp);  // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._HPP_file._fp);           // .hpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_file._fp);           // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_CLONE_file._fp);     // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_EXPAND_file._fp);    // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_FORMAT_file._fp);    // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_GEN_file._fp);       // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_MISC_file._fp);      // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_PEEPHOLE_file._fp);  // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._CPP_PIPELINE_file._fp);  // .cpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._VM_file._fp);            // .hpp
+  AD.addSunCopyright(legal_text, legal_sz, AD._DFA_file._fp);           // .cpp
   // Make sure each .cpp file starts with include lines:
   // files declaring and defining generators for Mach* Objects (hpp,cpp)
   AD.machineDependentIncludes(AD._CPP_file);      // .cpp
@@ -239,7 +244,6 @@
   AD.addPreprocessorChecks(AD._CPP_PIPELINE_file._fp);  // .cpp
 
   // define the finite automata that selects lowest cost production
-  AD.addSunCopyright(AD._DFA_file._fp);           // .cpp
   AD.machineDependentIncludes(AD._DFA_file);      // .cpp
   AD.buildDFA(AD._DFA_file._fp);
 
@@ -412,6 +416,24 @@
   return fname;
 }
 
+//------------------------------get_legal_text---------------------------------
+// Get pointer to legal text at the beginning of AD file.
+// This code assumes that a legal text starts at the beginning of .ad files,
+// is commented by "//" at each line and ends with empty line.
+// 
+int get_legal_text(FileBuff &fbuf, char **legal_text)
+{
+  char* legal_start = fbuf.get_line();
+  assert(legal_start[0] == '/' && legal_start[1] == '/', "Incorrect header of AD file");
+  char* legal_end = fbuf.get_line();
+  assert(strncmp(legal_end, "// Copyright", 12) == 0, "Incorrect header of AD file");
+  while(legal_end[0] == '/' && legal_end[1] == '/') {
+    legal_end = fbuf.get_line();
+  }
+  *legal_text = legal_start;
+  return (legal_end - legal_start);
+}
+
 // VS2005 has its own definition, identical to this one.
 #if !defined(_WIN32) || defined(_WIN64) || _MSC_VER < 1400
 void *operator new( size_t size, int, const char *, int ) {
--- a/hotspot/src/share/vm/classfile/dictionary.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)dictionary.cpp	1.26 07/05/17 15:50:16 JVM"
+#pragma ident "@(#)dictionary.cpp	1.27 08/06/19 10:32:36 JVM"
 #endif
 /*
  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -158,8 +158,8 @@
         for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
           // check the previous versions array for GC'ed weak refs
           PreviousVersionNode * pv_node = ik->previous_versions()->at(i);
-          jweak cp_ref = pv_node->prev_constant_pool();
-          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+          jobject cp_ref = pv_node->prev_constant_pool();
+          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
           if (cp_ref == NULL) {
             delete pv_node;
             ik->previous_versions()->remove_at(i);
--- a/hotspot/src/share/vm/gc_implementation/parNew/vmStructs_parNew.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parNew/vmStructs_parNew.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,11 +1,25 @@
-#ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)vmStructs_parNew.hpp	1.1 07/05/01 16:48:02 JVM"
-#endif
 /*
- * @(#)vmStructs_parNew.hpp	1.1 07/05/01
- * 
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
  */
 
 #define VM_TYPES_PARNEW(declare_type)                                     \
--- a/hotspot/src/share/vm/includeDB_core	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/includeDB_core	Thu Jul 10 00:00:00 2008 +0200
@@ -3395,6 +3395,7 @@
 
 oopMapCache.cpp                         allocation.inline.hpp
 oopMapCache.cpp                         handles.inline.hpp
+oopMapCache.cpp                         jvmtiRedefineClasses.hpp
 oopMapCache.cpp                         oop.inline.hpp
 oopMapCache.cpp                         oopMapCache.hpp
 oopMapCache.cpp                         resourceArea.hpp
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)oopMapCache.cpp	1.84 07/05/05 17:05:39 JVM"
+#pragma ident "@(#)oopMapCache.cpp	1.85 08/06/19 12:45:42 JVM"
 #endif
 /*
  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -535,6 +535,10 @@
     if (!_array[i].is_empty() && _array[i].method()->is_old()) {
       // Cache entry is occupied by an old redefined method and we don't want
       // to pin it down so flush the entry.
+      RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
+        _array[i].method()->name()->as_C_string(),
+        _array[i].method()->signature()->as_C_string(), i));
+
       _array[i].flush();
     }
 }
@@ -580,6 +584,15 @@
   // Entry is not in hashtable. 
   // Compute entry and return it
 
+  if (method->should_not_be_cached()) {
+    // It is either not safe or not a good idea to cache this methodOop
+    // at this time. We give the caller of lookup() a copy of the
+    // interesting info via parameter entry_for, but we don't add it to
+    // the cache. See the gory details in methodOop.cpp.
+    compute_one_oop_map(method, bci, entry_for);
+    return;
+  }
+
   // First search for an empty slot
   for(i = 0; i < _probe_depth; i++) {
     entry  = entry_at(probe + i);
@@ -587,12 +600,6 @@
       entry->fill(method, bci);
       entry_for->resource_copy(entry);
       assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
-      if (method->is_old()) {
-        // The caller of lookup() will receive a copy of the interesting
-        // info via entry_for, but we don't keep an old redefined method in
-        // the cache to avoid pinning down the method.
-        entry->flush();
-      }
       return; 
     }
   }
@@ -626,13 +633,6 @@
   }
   assert(!entry_for->is_empty(), "A non-empty oop map should be returned");
 
-  if (method->is_old()) {
-    // The caller of lookup() will receive a copy of the interesting
-    // info via entry_for, but we don't keep an old redefined method in
-    // the cache to avoid pinning down the method.
-    entry->flush();
-  }
-
   return;
 }
 
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)compactingPermGenGen.cpp	1.20 07/05/05 17:05:45 JVM"
+#pragma ident "@(#)compactingPermGenGen.cpp	1.21 08/06/19 10:32:37 JVM"
 #endif
 /*
  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -29,9 +29,27 @@
 #include "incls/_compactingPermGenGen.cpp.incl"
 
 
-// Recursively adjust all pointers in an object and all objects by
-// referenced it.  Clear marks on objects in order to prevent visiting
-// any object twice.
+// An ObjectClosure helper: Recursively adjust all pointers in an object
+// and all objects by referenced it. Clear marks on objects in order to
+// prevent visiting any object twice. This helper is used when the
+// RedefineClasses() API has been called.
+
+class AdjustSharedObjectClosure : public ObjectClosure {
+public:
+  void do_object(oop obj) {
+    if (obj->is_shared_readwrite()) {
+      if (obj->mark()->is_marked()) {
+        obj->init_mark();         // Don't revisit this object.
+        obj->adjust_pointers();   // Adjust this object's references.
+      }
+    }
+  }
+};
+
+
+// An OopClosure helper: Recursively adjust all pointers in an object
+// and all objects by referenced it. Clear marks on objects in order
+// to prevent visiting any object twice.
 
 class RecursiveAdjustSharedObjectClosure : public OopClosure {
 public:
@@ -277,15 +295,34 @@
 // objects in the space will page in more objects than we need.
 // Instead, use the system dictionary as strong roots into the read
 // write space.
+//
+// If a RedefineClasses() call has been made, then we have to iterate
+// over the entire shared read-write space in order to find all the
+// objects that need to be forwarded. For example, it is possible for
+// an nmethod to be found and marked in GC phase-1 only for the nmethod
+// to be freed by the time we reach GC phase-3. The underlying method
+// is still marked, but we can't (easily) find it in GC phase-3 so we
+// blow up in GC phase-4. With RedefineClasses() we want replaced code
+// (EMCP or obsolete) to go away (i.e., be collectible) once it is no
+// longer being executed by any thread so we keep minimal attachments
+// to the replaced code. However, we can't guarantee when those EMCP
+// or obsolete methods will be collected so they may still be out there
+// even after we've severed our minimal attachments.
 
 void CompactingPermGenGen::pre_adjust_pointers() {
   if (spec()->enable_shared_spaces()) {
-    RecursiveAdjustSharedObjectClosure blk;
-    Universe::oops_do(&blk);
-    StringTable::oops_do(&blk);
-    SystemDictionary::always_strong_classes_do(&blk);
-    TraversePlaceholdersClosure tpc;
-    SystemDictionary::placeholders_do(&tpc);
+    if (JvmtiExport::has_redefined_a_class()) {
+      // RedefineClasses() requires a brute force approach
+      AdjustSharedObjectClosure blk;
+      rw_space()->object_iterate(&blk);
+    } else {
+      RecursiveAdjustSharedObjectClosure blk;
+      Universe::oops_do(&blk);
+      StringTable::oops_do(&blk);
+      SystemDictionary::always_strong_classes_do(&blk);
+      TraversePlaceholdersClosure tpc;
+      SystemDictionary::placeholders_do(&tpc);
+    }
   }
 }
 
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)instanceKlass.cpp	1.322 07/05/29 09:44:19 JVM"
+#pragma ident "@(#)instanceKlass.cpp	1.323 08/06/19 10:32:38 JVM"
 #endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -2140,12 +2140,20 @@
   RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
     ikh->external_name(), _previous_versions->length(), emcp_method_count));
   constantPoolHandle cp_h(ikh->constants());
-  jweak cp_ref = JNIHandles::make_weak_global(cp_h);
+  jobject cp_ref;
+  if (cp_h->is_shared()) {
+    // a shared ConstantPool requires a regular reference; a weak
+    // reference would be collectible
+    cp_ref = JNIHandles::make_global(cp_h);
+  } else {
+    cp_ref = JNIHandles::make_weak_global(cp_h);
+  }
   PreviousVersionNode * pv_node = NULL;
   objArrayOop old_methods = ikh->methods();
 
   if (emcp_method_count == 0) {
-    pv_node = new PreviousVersionNode(cp_ref, NULL);
+    // non-shared ConstantPool gets a weak reference
+    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
     RC_TRACE(0x00000400,
       ("add: all methods are obsolete; flushing any EMCP weak refs"));
   } else {
@@ -2165,7 +2173,8 @@
         }
       }
     }
-    pv_node = new PreviousVersionNode(cp_ref, method_refs);
+    // non-shared ConstantPool gets a weak reference
+    pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs);
   }
 
   _previous_versions->append(pv_node);
@@ -2183,7 +2192,7 @@
     // check the previous versions array for a GC'ed weak refs
     pv_node = _previous_versions->at(i);
     cp_ref = pv_node->prev_constant_pool();
-    assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+    assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
     if (cp_ref == NULL) {
       delete pv_node;
       _previous_versions->remove_at(i);
@@ -2256,7 +2265,7 @@
           // check the previous versions array for a GC'ed weak refs
           pv_node = _previous_versions->at(j);
           cp_ref = pv_node->prev_constant_pool();
-          assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared");
+          assert(cp_ref != NULL, "cp ref was unexpectedly cleared");
           if (cp_ref == NULL) {
             delete pv_node;
             _previous_versions->remove_at(j);
@@ -2354,8 +2363,8 @@
     // been GC'ed
     PreviousVersionNode * pv_node = _previous_versions->at(i);
 
-    jweak cp_ref = pv_node->prev_constant_pool();
-    assert(cp_ref != NULL, "weak reference was unexpectedly cleared");
+    jobject cp_ref = pv_node->prev_constant_pool();
+    assert(cp_ref != NULL, "cp reference was unexpectedly cleared");
     if (cp_ref == NULL) {
       continue;  // robustness
     }
@@ -2415,10 +2424,11 @@
 
 // Construct a PreviousVersionNode entry for the array hung off
 // the instanceKlass.
-PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool,
-  GrowableArray<jweak>* prev_EMCP_methods) {
+PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool,
+  bool prev_cp_is_weak, GrowableArray<jweak>* prev_EMCP_methods) {
 
   _prev_constant_pool = prev_constant_pool;
+  _prev_cp_is_weak = prev_cp_is_weak;
   _prev_EMCP_methods = prev_EMCP_methods;
 }
 
@@ -2426,7 +2436,11 @@
 // Destroy a PreviousVersionNode
 PreviousVersionNode::~PreviousVersionNode() {
   if (_prev_constant_pool != NULL) {
-    JNIHandles::destroy_weak_global(_prev_constant_pool);
+    if (_prev_cp_is_weak) {
+      JNIHandles::destroy_weak_global(_prev_constant_pool);
+    } else {
+      JNIHandles::destroy_global(_prev_constant_pool);
+    }
   }
 
   if (_prev_EMCP_methods != NULL) {
@@ -2446,8 +2460,8 @@
   _prev_constant_pool_handle = constantPoolHandle();  // NULL handle
   _prev_EMCP_method_handles = NULL;
 
-  jweak cp_ref = pv_node->prev_constant_pool();
-  assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared");
+  jobject cp_ref = pv_node->prev_constant_pool();
+  assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared");
   if (cp_ref == NULL) {
     return;  // robustness
   }
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)instanceKlass.hpp	1.199 07/05/29 09:44:20 JVM"
+#pragma ident "@(#)instanceKlass.hpp	1.200 08/06/19 10:32:39 JVM"
 #endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -818,11 +818,20 @@
 // A collection point for interesting information about the previous
 // version(s) of an instanceKlass. This class uses weak references to
 // the information so that the information may be collected as needed
-// by the system. A GrowableArray of PreviousVersionNodes is attached
+// by the system. If the information is shared, then a regular
+// reference must be used because a weak reference would be seen as
+// collectible. A GrowableArray of PreviousVersionNodes is attached
 // to the instanceKlass as needed. See PreviousVersionWalker below.
 class PreviousVersionNode : public CHeapObj {
  private:
-  jweak _prev_constant_pool;
+  // A shared ConstantPool is never collected so we'll always have
+  // a reference to it so we can update items in the cache. We'll
+  // have a weak reference to a non-shared ConstantPool until all
+  // of the methods (EMCP or obsolete) have been collected; the
+  // non-shared ConstantPool becomes collectible at that point.
+  jobject _prev_constant_pool;  // regular or weak reference
+  bool    _prev_cp_is_weak;     // true if not a shared ConstantPool
+
   // If the previous version of the instanceKlass doesn't have any
   // EMCP methods, then _prev_EMCP_methods will be NULL. If all the
   // EMCP methods have been collected, then _prev_EMCP_methods can
@@ -830,10 +839,10 @@
   GrowableArray<jweak>* _prev_EMCP_methods;
 
 public:
-  PreviousVersionNode(jweak prev_constant_pool,
+  PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak,
     GrowableArray<jweak>* prev_EMCP_methods);
   ~PreviousVersionNode();
-  jweak prev_constant_pool() const {
+  jobject prev_constant_pool() const {
     return _prev_constant_pool;
   }
   GrowableArray<jweak>* prev_EMCP_methods() const {
--- a/hotspot/src/share/vm/oops/markOop.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/oops/markOop.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)markOop.cpp	1.28 07/05/05 17:06:05 JVM"
+#pragma ident "@(#)markOop.cpp	1.29 08/06/19 12:45:44 JVM"
 #endif
 /*
  * Copyright 1997-1999 Sun Microsystems, Inc.  All Rights Reserved.
@@ -40,3 +40,32 @@
     st->print("age %d)", age());
   }
 }
+
+
+// Give advice about whether the oop that contains this markOop
+// should be cached or not.
+bool markOopDesc::should_not_be_cached() const {
+  // the cast is because decode_pointer() isn't marked const
+  if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) {
+    // If the oop containing this markOop is being forwarded, then
+    // we are in the middle of GC and we do not want the containing
+    // oop to be added to a cache. We have no way of knowing whether
+    // the cache has already been visited by the current GC phase so
+    // we don't know whether the forwarded oop will be properly
+    // processed in this phase. If the forwarded oop is not properly
+    // processed, then we'll see strange crashes or asserts during
+    // the next GC run because the markOop will contain an unexpected
+    // value.
+    //
+    // This situation has been seen when we are GC'ing a methodOop
+    // because we use the methodOop while we're GC'ing it. Scary
+    // stuff. Some of the uses the methodOop cause the methodOop to
+    // be added to the OopMapCache in the instanceKlass as a side
+    // effect. This check lets the cache maintainer know when a
+    // cache addition would not be safe.
+    return true;
+  }
+
+  // caching the containing oop should be just fine
+  return false;
+}
--- a/hotspot/src/share/vm/oops/markOop.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/oops/markOop.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)markOop.hpp	1.64 07/05/05 17:06:02 JVM"
+#pragma ident "@(#)markOop.hpp	1.65 08/06/19 12:45:45 JVM"
 #endif
 /*
  * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -360,4 +360,7 @@
 
   // Recover address of oop from encoded form used in mark
   inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); }
+
+  // see the definition in markOop.cpp for the gory details
+  bool should_not_be_cached() const;
 };
--- a/hotspot/src/share/vm/oops/methodOop.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/oops/methodOop.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)methodOop.cpp	1.312 07/06/08 15:21:45 JVM"
+#pragma ident "@(#)methodOop.cpp	1.313 08/06/19 12:45:47 JVM"
 #endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -768,6 +768,28 @@
 }
 
 
+// give advice about whether this methodOop should be cached or not
+bool methodOopDesc::should_not_be_cached() const {
+  if (is_old()) {
+    // This method has been redefined. It is either EMCP or obsolete
+    // and we don't want to cache it because that would pin the method
+    // down and prevent it from being collectible if and when it
+    // finishes executing.
+    return true;
+  }
+
+  if (mark()->should_not_be_cached()) {
+    // It is either not safe or not a good idea to cache this
+    // method at this time because of the state of the embedded
+    // markOop. See markOop.cpp for the gory details.
+    return true;
+  }
+
+  // caching this method should be just fine
+  return false;
+}
+
+
 methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length, 
                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
   // Code below does not work for native methods - they should never get rewritten anyway
--- a/hotspot/src/share/vm/oops/methodOop.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/oops/methodOop.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)methodOop.hpp	1.219 07/05/17 15:57:04 JVM"
+#pragma ident "@(#)methodOop.hpp	1.220 08/06/19 12:45:48 JVM"
 #endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -524,6 +524,8 @@
   void set_is_old()                                 { _access_flags.set_is_old(); }
   bool is_obsolete() const                          { return access_flags().is_obsolete(); }
   void set_is_obsolete()                            { _access_flags.set_is_obsolete(); }
+  // see the definition in methodOop.cpp for the gory details
+  bool should_not_be_cached() const;
 
   // JVMTI Native method prefixing support:
   bool is_prefixed_native() const                   { return access_flags().is_prefixed_native(); }
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)cfgnode.cpp	1.260 07/05/17 15:57:27 JVM"
+#pragma ident "@(#)cfgnode.cpp	1.261 08/06/22 00:57:20 JVM"
 #endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -1551,45 +1551,6 @@
     if (opt != NULL)  return opt;
   }
 
-  if (in(1) != NULL && in(1)->Opcode() == Op_AddP && can_reshape) {
-    // Try to undo Phi of AddP:
-    //   (Phi (AddP base base y) (AddP base2 base2 y))
-    // becomes:
-    //   newbase := (Phi base base2)
-    //   (AddP newbase newbase y)
-    //
-    // This occurs as a result of unsuccessful split_thru_phi and
-    // interferes with taking advantage of addressing modes.  See the
-    // clone_shift_expressions code in matcher.cpp
-    Node* addp = in(1);
-    const Type* type = addp->in(AddPNode::Base)->bottom_type();
-    Node* y = addp->in(AddPNode::Offset);
-    if (y != NULL && addp->in(AddPNode::Base) == addp->in(AddPNode::Address)) {
-      // make sure that all the inputs are similar to the first one,
-      // i.e. AddP with base == address and same offset as first AddP
-      bool doit = true;
-      for (uint i = 2; i < req(); i++) {
-        if (in(i) == NULL ||
-            in(i)->Opcode() != Op_AddP ||
-            in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) ||
-            in(i)->in(AddPNode::Offset) != y) {
-          doit = false;
-          break;
-        }
-        // Accumulate type for resulting Phi
-        type = type->meet(in(i)->in(AddPNode::Base)->bottom_type());
-      }
-      if (doit) {
-        Node* base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL);
-        for (uint i = 1; i < req(); i++) {
-          base->init_req(i, in(i)->in(AddPNode::Base));
-        }
-        phase->is_IterGVN()->register_new_node_with_optimizer(base);
-        return new (phase->C, 4) AddPNode(base, base, y);
-      }
-    }
-  }
-
   // Split phis through memory merges, so that the memory merges will go away.
   // Piggy-back this transformation on the search for a unique input....
   // It will be as if the merged memory is the unique value of the phi.
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)loopopts.cpp	1.220 07/06/29 13:39:54 JVM"
+#pragma ident "@(#)loopopts.cpp	1.221 08/06/19 12:08:11 JVM"
 #endif
 /*
  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -32,6 +32,11 @@
 //------------------------------split_thru_phi---------------------------------
 // Split Node 'n' through merge point if there is enough win.
 Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
+  if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) {
+    // ConvI2L may have type information on it which is unsafe to push up
+    // so disable this for now
+    return NULL;
+  }
   int wins = 0;
   assert( !n->is_CFG(), "" );
   assert( region->is_Region(), "" );
--- a/hotspot/src/share/vm/opto/memnode.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)memnode.cpp	1.237 07/05/17 15:59:18 JVM"
+#pragma ident "@(#)memnode.cpp	1.238 08/06/19 10:10:54 JVM"
 #endif
 /*
  * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
@@ -1320,9 +1320,16 @@
 
 //------------------------------Value-----------------------------------------
 const Type *StoreCMNode::Value( PhaseTransform *phase ) const {
+  // Either input is TOP ==> the result is TOP
+  const Type *t = phase->type( in(MemNode::Memory) );
+  if( t == Type::TOP ) return Type::TOP;
+  t = phase->type( in(MemNode::Address) );
+  if( t == Type::TOP ) return Type::TOP;
+  t = phase->type( in(MemNode::ValueIn) );
+  if( t == Type::TOP ) return Type::TOP;
   // If extra input is TOP ==> the result is TOP
-  const Type *t1 = phase->type( in(MemNode::OopStore) );
-  if( t1 == Type::TOP ) return Type::TOP;
+  t = phase->type( in(MemNode::OopStore) );
+  if( t == Type::TOP ) return Type::TOP;
 
   return StoreNode::Value( phase );
 }
--- a/hotspot/src/share/vm/opto/parse3.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/opto/parse3.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)parse3.cpp	1.267 07/11/21 11:31:54 JVM"
+#pragma ident "@(#)parse3.cpp	1.268 08/04/22 01:46:50 JVM"
 #endif
 /*
  * Copyright 1998-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -398,7 +398,7 @@
   // fill the lowest dimensions with unknown sizes
   for (int index = 0; index < mdimensions - ndimensions; index++) {
     const TypeAry* arr0 = TypeAry::make(prev_type, TypeInt::POS);
-    prev_type = TypeAryPtr::make(TypePtr::BotPTR, arr0, prev_array, true, 0);
+    prev_type = TypeAryPtr::make(TypePtr::BotPTR, arr0, prev_array, false, 0);
     prev_array = NULL; // array klasses can be lazy, except the first
   }
 
--- a/hotspot/src/share/vm/prims/jvmti.xml	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/prims/jvmti.xml	Thu Jul 10 00:00:00 2008 +0200
@@ -30,7 +30,7 @@
    <!ATTLIST specification label CDATA #REQUIRED 
                            majorversion CDATA #REQUIRED 
                            minorversion CDATA #REQUIRED 
-                           onedotmicroversion CDATA #REQUIRED>
+                           microversion CDATA #REQUIRED>
 
    <!ELEMENT title (#PCDATA|jvmti|tm)*>
    <!ATTLIST title subtitle CDATA #REQUIRED>
@@ -248,7 +248,6 @@
 
    <!ELEMENT changehistory (intro*, change*)>
    <!ATTLIST changehistory update CDATA #REQUIRED
-                           version CDATA #REQUIRED
                            id CDATA #REQUIRED>
 
    <!ELEMENT change ANY>
@@ -360,7 +359,7 @@
 <specification label="JVM(TM) Tool Interface"
         majorversion="1"
         minorversion="1"
-        onedotmicroversion="1.206">
+        microversion="102">
   <title subtitle="Version">
     <tm>JVM</tm> Tool Interface
   </title>
@@ -13383,7 +13382,7 @@
   </intro>
 </issuessection>
 
-<changehistory id="ChangeHistory" version="@(#)jvmti.xml	1.206" update="07/05/05 17:06:33">
+<changehistory id="ChangeHistory" update="06/08/06">
   <intro>
     The <jvmti/> specification is an evolving document with major, minor, 
     and micro version numbers.
--- a/hotspot/src/share/vm/prims/jvmti.xsl	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/prims/jvmti.xsl	Thu Jul 10 00:00:00 2008 +0200
@@ -1891,7 +1891,6 @@
     <p/><hr noshade="noshade" size="3"/>
     <h2>Change History</h2>
     Last update: <xsl:value-of select="@update"/><br/>
-    File version: <xsl:value-of select="@version"/><br/>
     Version: <xsl:call-template name="showversion"/>
     <p/>
     <xsl:apply-templates select="intro"/>
--- a/hotspot/src/share/vm/prims/jvmtiLib.xsl	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiLib.xsl	Thu Jul 10 00:00:00 2008 +0200
@@ -27,18 +27,8 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 version="1.0">
 
-  <xsl:variable name="microversionbase" select="100"/>
-
   <xsl:template name="microversion">
-    <xsl:variable name="micro" select="substring-after(//specification/@onedotmicroversion, '1.')"/>
-    <xsl:choose>
-      <xsl:when test="string($micro)=''">
-        <xsl:text>dev</xsl:text>
-      </xsl:when>
-      <xsl:otherwise>
-        <xsl:value-of select="$micro - $microversionbase"/>
-      </xsl:otherwise>
-    </xsl:choose>
+    <xsl:value-of select="//specification/@microversion"/>
   </xsl:template>
 
   <xsl:template name="showbasicversion">
@@ -53,32 +43,21 @@
     <xsl:call-template name="microversion"/>
   </xsl:template>
 
+  <xsl:template name="copyrightComment">
+    <xsl:text>/* </xsl:text>
+    <!-- Copy the Copyright comment from jvmti.xml -->
+    <xsl:value-of select="/comment()[position()=1]"/>
+    <xsl:text> */ &#xA;&#xA;</xsl:text>
+  </xsl:template>
+
   <xsl:template name="includeHeader">
-    <xsl:text>#ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)jvmtiLib.xsl	1.43 07/05/05 17:06:39 JVM"
-#endif
-/*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
- */
-
-    /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */
-
-</xsl:text>    
+    <xsl:call-template name="copyrightComment"/>
+    <xsl:text> /* AUTOMATICALLY GENERATED FILE - DO NOT EDIT */ &#xA;</xsl:text>    
   </xsl:template>
 
   <xsl:template name="sourceHeader">
-    <xsl:text>#ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)jvmtiLib.xsl	1.43 07/05/05 17:06:39 JVM"
-#endif
-/*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
- */
-
-  // AUTOMATICALLY GENERATED FILE - DO NOT EDIT
-
-</xsl:text>    
+    <xsl:call-template name="copyrightComment"/>
+    <xsl:text> // AUTOMATICALLY GENERATED FILE - DO NOT EDIT &#xA;</xsl:text>    
   </xsl:template>
 
 
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,5 +1,5 @@
 #ifdef USE_PRAGMA_IDENT_HDR
-#pragma ident "@(#)jvmtiRedefineClasses.hpp	1.40 07/05/23 10:53:53 JVM"
+#pragma ident "@(#)jvmtiRedefineClasses.hpp	1.41 08/06/19 12:45:49 JVM"
 #endif
 /*
  * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
@@ -377,7 +377,7 @@
 //    0x01000000 |   16777216 - impl details: nmethod evolution info
 //    0x02000000 |   33554432 - impl details: annotation updates
 //    0x04000000 |   67108864 - impl details: StackMapTable updates
-//    0x08000000 |  134217728 - unused
+//    0x08000000 |  134217728 - impl details: OopMapCache updates
 //    0x10000000 |  268435456 - unused
 //    0x20000000 |  536870912 - unused
 //    0x40000000 | 1073741824 - unused
--- a/hotspot/src/share/vm/utilities/copy.cpp	Fri May 30 00:00:00 2008 +0200
+++ b/hotspot/src/share/vm/utilities/copy.cpp	Thu Jul 10 00:00:00 2008 +0200
@@ -1,9 +1,25 @@
-#ifdef USE_PRAGMA_IDENT_SRC
-#pragma ident "@(#)copy.cpp	1.2 07/04/13 10:35:00 JVM"
-#endif
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
- * SUN PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
+ * Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
  */
 
 # include "incls/_precompiled.incl"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6659207/Test.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 1997-2002 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 6659207
+ * @summary access violation in CompilerThread0
+ */
+
+public class Test {
+    static int[] array = new int[12];
+
+    static int index(int i) {
+        if (i == 0) return 0;
+        for (int n = 0; n < array.length; n++)
+            if (i < array[n]) return n;
+        return -1;
+    }
+
+    static int test(int i) {
+        int result = 0;
+        i = index(i);
+        if (i >= 0)
+            if (array[i] != 0)
+                result++;
+
+        if (i != -1)
+            array[i]++;
+
+        return result;
+    }
+
+    public static void main(String[] args) {
+        int total = 0;
+        for (int i = 0; i < 100000; i++) {
+            total += test(10);
+        }
+        System.out.println(total);
+    }
+}
--- a/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java	Fri May 30 00:00:00 2008 +0200
+++ b/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/PropertyManager.java	Thu Jul 10 00:00:00 2008 +0200
@@ -45,8 +45,8 @@
 public class PropertyManager {
 
 
-    protected static final String STAX_NOTATIONS = "javax.xml.stream.notations";
-    protected static final String STAX_ENTITIES = "javax.xml.stream.entities";
+    public static final String STAX_NOTATIONS = "javax.xml.stream.notations";
+    public static final String STAX_ENTITIES = "javax.xml.stream.entities";
 
     private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning";
 
--- a/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Fri May 30 00:00:00 2008 +0200
+++ b/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java	Thu Jul 10 00:00:00 2008 +0200
@@ -289,6 +289,8 @@
     protected boolean fReportCdataEvent = false ;
     protected boolean fIsCoalesce = false ;
     protected String fDeclaredEncoding =  null;
+    /** Disallow doctype declaration. */
+    protected boolean fDisallowDoctype = false;
 
     // drivers
 
@@ -1852,6 +1854,11 @@
         }
         // start general entity
         if (!fEntityStore.isDeclaredEntity(name)) {
+            //SUPPORT_DTD=false && ReplaceEntityReferences should throw exception
+            if (fDisallowDoctype && fReplaceEntityReferences) {
+                reportFatalError("EntityNotDeclared", new Object[]{name});
+                return;
+            }
             //REVISIT: one more case needs to be included: external PE and standalone is no
             if ( fHasExternalDTD && !fStandalone) {
                 if (fValidation)
--- a/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java	Fri May 30 00:00:00 2008 +0200
+++ b/jaxp/src/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentScannerImpl.java	Thu Jul 10 00:00:00 2008 +0200
@@ -62,6 +62,9 @@
  * @author Arnaud  Le Hors, IBM
  * @author Eric Ye, IBM
  * @author Sunitha Reddy, Sun Microsystems
+ * Refer to the table in unit-test javax.xml.stream.XMLStreamReaderTest.SupportDTD for changes
+ * related to property SupportDTD.
+ * @author Joe Wang, Sun Microsystems
  */
 public class XMLDocumentScannerImpl
         extends XMLDocumentFragmentScannerImpl{
@@ -185,9 +188,6 @@
     /** Load external DTD. */
     protected boolean fLoadExternalDTD = true;
 
-    /** Disallow doctype declaration. */
-    protected boolean fDisallowDoctype = false;
-
     // state
 
     /** Seen doctype declaration. */
@@ -227,8 +227,8 @@
     /** String. */
     private XMLString fString = new XMLString();
 
-    public static final char [] DOCTYPE = {'D','O','C','T','Y','P','E'};
-    public static final char [] COMMENTSTRING = {'-','-'};
+    private static final char [] DOCTYPE = {'D','O','C','T','Y','P','E'};
+    private static final char [] COMMENTSTRING = {'-','-'};
 
     //
     // Constructors
@@ -708,6 +708,12 @@
     //
     // Private methods
     //
+    /** Set the scanner state after scanning DTD */
+    protected void setEndDTDScanState() {
+        setScannerState(SCANNER_STATE_PROLOG);
+        setDriver(fPrologDriver);
+        fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
+    }
 
     /** Returns the scanner state name. */
     protected String getScannerStateName(int state) {
@@ -930,19 +936,21 @@
                             reportFatalError("AlreadySeenDoctype", null);
                         }
                         fSeenDoctypeDecl = true;
-                        if(fDTDDriver == null){
-                            fDTDDriver = new DTDDriver();
-                        }
 
                         // scanDoctypeDecl() sends XNI doctypeDecl event that
                         // in SAX is converted to startDTD() event.
                         if (scanDoctypeDecl(fDisallowDoctype)) {
+                            //allow parsing of entity decls to continue in order to stay well-formed
                             setScannerState(SCANNER_STATE_DTD_INTERNAL_DECLS);
                             fSeenInternalSubset = true;
+                            if(fDTDDriver == null){
+                                fDTDDriver = new DTDDriver();
+                            }
                             setDriver(fContentDriver);
-                            int dtdEvent = fDTDDriver.next();
+                            //always return DTD event, the event however, will not contain any entities
+                            return fDTDDriver.next();
                             // If no DTD support, ignore and continue parsing
-                            return fDisallowDoctype ? next() : dtdEvent;
+                            //return fDisallowDoctype ? next() : dtdEvent;
                         }
 
                         /** xxx:check this part again
@@ -955,17 +963,18 @@
                         }
                          */
 
-                        if (fDisallowDoctype) {
-                            setScannerState(SCANNER_STATE_PROLOG);
-                            return next();
-                        }
-
                         // handle external subset
                         if (fDoctypeSystemId != null) {
                             if (((fValidation || fLoadExternalDTD)
                                 && (fValidationManager == null || !fValidationManager.isCachedDTD()))) {
-                                setScannerState(SCANNER_STATE_DTD_EXTERNAL);
+                                if (!fDisallowDoctype) {
+                                    setScannerState(SCANNER_STATE_DTD_EXTERNAL);
+                                } else {
+                                    setScannerState(SCANNER_STATE_PROLOG);
+                                }
                                 setDriver(fContentDriver);
+                                if(fDTDDriver == null)
+                                    fDTDDriver = new DTDDriver();
                                 return fDTDDriver.next();
 
                             }
@@ -976,8 +985,14 @@
                                 // This handles the case of a DOCTYPE that had neither an internal subset or an external subset.
                                 fDTDScanner.setInputSource(fExternalSubsetSource);
                                 fExternalSubsetSource = null;
-                                setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
+                                if (!fDisallowDoctype) {
+                                    setScannerState(SCANNER_STATE_DTD_EXTERNAL_DECLS);
+                                } else {
+                                    setScannerState(SCANNER_STATE_PROLOG);
+                                }
                                 setDriver(fContentDriver);
+                                if(fDTDDriver == null)
+                                    fDTDDriver = new DTDDriver();
                                 return fDTDDriver.next();
                             }
                         }
@@ -1117,19 +1132,21 @@
                                 }
                                 fMarkupDepth--;
 
-                                // scan external subset next
-                                if (!XMLDocumentScannerImpl.this.fDisallowDoctype &&
-                                        fDoctypeSystemId != null && (fValidation || fLoadExternalDTD)) {
-                                    setScannerState(SCANNER_STATE_DTD_EXTERNAL);
+                                if (fDisallowDoctype) {
+                                    //simply reset the entity store without having to mess around
+                                    //with the DTD Scanner code
+                                    fEntityStore = fEntityManager.getEntityStore();
+                                    fEntityStore.reset();
+                                } else {
+                                    // scan external subset next unless we are ignoring DTDs
+                                    if (fDoctypeSystemId != null && (fValidation || fLoadExternalDTD)) {
+                                        setScannerState(SCANNER_STATE_DTD_EXTERNAL);
+                                        break;
+                                    }
                                 }
+                                setEndDTDScanState();
 
-                                // break out of here
-                                else {
-                                    setScannerState(SCANNER_STATE_PROLOG);
-                                    setDriver(fPrologDriver);
-                                    fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
-                                    return true;
-                                }
+                                return true;
                             }
                             break;
                         }
@@ -1160,13 +1177,16 @@
                             boolean completeDTD = true;
                             boolean moreToScan = fDTDScanner.scanDTDExternalSubset(completeDTD);
                             if (!moreToScan) {
-                                setScannerState(SCANNER_STATE_PROLOG);
-                                setDriver(fPrologDriver);
-                                fEntityManager.setEntityHandler(XMLDocumentScannerImpl.this);
+                                setEndDTDScanState();
                                 return true;
                             }
                             break;
                         }
+                        case SCANNER_STATE_PROLOG : {
+                            // skip entity decls
+                            setEndDTDScanState();
+                            return true;
+                        }
                         default: {
                             throw new XNIException("DTDDriver#dispatch: scanner state="+fScannerState+" ("+getScannerStateName(fScannerState)+')');
                         }
--- a/jaxp/src/share/classes/com/sun/org/apache/xml/internal/utils/ThreadControllerWrapper.java	Fri May 30 00:00:00 2008 +0200
+++ b/jaxp/src/share/classes/com/sun/org/apache/xml/internal/utils/ThreadControllerWrapper.java	Thu Jul 10 00:00:00 2008 +0200
@@ -53,7 +53,35 @@
   {
 
     /**
-     * Will get a thread from the pool, execute the task
+      * This class was introduced as a fix for CR 6607339.
+      */
+     final class SafeThread extends Thread {
+          private volatile boolean ran = false;
+                  
+          public SafeThread(Runnable target) {
+              super(target);
+          }
+                  
+          public final void run() {
+              if (Thread.currentThread() != this) {
+                  throw new IllegalStateException("The run() method in a"
+                      + " SafeThread cannot be called from another thread.");
+              }
+              synchronized (this) {
+                 if (!ran) {
+                     ran = true;
+                 }
+                 else {
+                  throw new IllegalStateException("The run() method in a"
+                      + " SafeThread cannot be called more than once.");
+                 }                 
+              }             
+              super.run();
+          }
+     }
+ 
+     /**
+     *  Will get a thread from the pool, execute the task
      *  and return the thread to the pool.
      *
      *  The return value is used only to wait for completion
@@ -68,7 +96,7 @@
     public Thread run(Runnable task, int priority)
     {
 
-      Thread t = new Thread(task);
+      Thread t = new SafeThread(task);
 
       t.start();
 
--- a/jaxp/src/share/classes/com/sun/xml/internal/stream/events/XMLEventAllocatorImpl.java	Fri May 30 00:00:00 2008 +0200
+++ b/jaxp/src/share/classes/com/sun/xml/internal/stream/events/XMLEventAllocatorImpl.java	Thu Jul 10 00:00:00 2008 +0200
@@ -25,6 +25,8 @@
 
 package com.sun.xml.internal.stream.events;
 
+import com.sun.org.apache.xerces.internal.impl.PropertyManager;
+import java.util.List;
 import javax.xml.stream.util.XMLEventAllocator;
 import javax.xml.stream.*;
 import javax.xml.stream.events.*;
@@ -144,7 +146,13 @@
                 break;
             }
             case XMLEvent.DTD:{
-                event = new DTDEvent(streamReader.getText());
+                DTDEvent dtdEvent = new DTDEvent(streamReader.getText());
+                dtdEvent.setLocation(streamReader.getLocation());
+                List entities = (List)streamReader.getProperty(PropertyManager.STAX_ENTITIES);
+                if (entities != null && entities.size() != 0) dtdEvent.setEntities(entities);
+                List notations = (List)streamReader.getProperty(PropertyManager.STAX_NOTATIONS);
+                if (notations != null && notations.size() != 0) dtdEvent.setNotations(notations);
+                event = dtdEvent;
                 break;
             }
             case XMLEvent.CDATA:{
--- a/jaxws/src/share/classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java	Fri May 30 00:00:00 2008 +0200
+++ b/jaxws/src/share/classes/com/sun/xml/internal/ws/api/streaming/XMLStreamReaderFactory.java	Thu Jul 10 00:00:00 2008 +0200
@@ -60,6 +60,7 @@
     static {
         XMLInputFactory xif = XMLInputFactory.newInstance();
         xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
+        xif.setProperty(XMLInputFactory.SUPPORT_DTD, false);
 
         XMLStreamReaderFactory f=null;
 
--- a/jdk/make/THIRD_PARTY_README	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/THIRD_PARTY_README	Thu Jul 10 00:00:00 2008 +0200
@@ -137,16 +137,6 @@
 The name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.
 ____________________________________
 This formulation of W3C's notice and license became active on August 14 1998 so as to improve compatibility with GPL. This version ensures that W3C software licensing terms are no more restrictive than GPL and consequently W3C software may be distributed in GPL packages. See the older formulation for the policy prior to this date. Please see our Copyright FAQ for common questions about using materials from our site, including specific terms and conditions for packages like libwww, Amaya, and Jigsaw. Other questions about this notice can be directed to site-policy@w3.org.

-%% This notice is provided with respect to jscheme.jar, which may be included with this software: 
-Software License Agreement
-Copyright © 1998-2002 by Peter Norvig. 
-Permission is granted to anyone to use this software, in source or object code form, on any computer system, and to modify, compile, decompile, run, and redistribute it to anyone else, subject to the following restrictions: 
-1.The author makes no warranty of any kind, either expressed or implied, about the suitability of this software for any purpose.
-2.The author accepts no liability of any kind for damages or other consequences of the use of this software, even if they arise from defects in the software.
-3.The origin of this software must not be misrepresented, either by explicit claim or by omission.
-4.Altered versions must be plainly marked as such, and must not be misrepresented as being the original software. Altered versions may be distributed in packages under other licenses (such as the GNU license). 
-If you find this software useful, it would be nice if you let me (peter@norvig.com) know about it, and nicer still if you send me modifications that you are willing to share. However, you are not required to do so.
 
 
 %% This notice is provided with respect to PC/SC Lite for Suse Linux v. 1.1.1, which may be included with this software: 
--- a/jdk/make/common/shared/Defs-utils.gmk	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/common/shared/Defs-utils.gmk	Thu Jul 10 00:00:00 2008 +0200
@@ -157,13 +157,15 @@
     ECHO = $(UNIXCOMMAND_PATH)echo -e
     ZIPEXE = $(UNIXCOMMAND_PATH)zip
     UNZIP  = $(UNIXCOMMAND_PATH)unzip
+    # Some CYGWIN nawk versions require BINMODE=w for proper '\r' interpretation
+    NAWK   = $(UNIXCOMMAND_PATH)awk -v BINMODE=w
   else
     ZIPEXE = $(UTILS_DEVTOOL_PATH)zip
     UNZIP  = $(UTILS_DEVTOOL_PATH)unzip
+    NAWK   = $(UNIXCOMMAND_PATH)awk
   endif
   # Re-define some utilities
   LEX            =# override GNU Make intrinsic: no lex on windows
-  NAWK           = $(UNIXCOMMAND_PATH)awk
 endif
 
 # Linux specific
--- a/jdk/make/common/shared/Platform.gmk	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/common/shared/Platform.gmk	Thu Jul 10 00:00:00 2008 +0200
@@ -72,7 +72,6 @@
 #     ISA_DIR                     solaris only: /sparcv9 or /amd64
 #     LIBARCH32                   solaris only: sparc or i386
 #     LIBARCH64                   solaris only: sparcv9 or amd64
-#     REQUIRED_WINDOWS_NAME       windows only: basic name of windows 
 #     REQUIRED_WINDOWS_VERSION    windows only: specific version of windows 
 #     USING_CYGWIN                windows only: true or false
 #     WINDOWS_NT_VERSION_STRING   windows only: long version name
@@ -315,19 +314,11 @@
     endif
   endif
   export ARCH_DATA_MODEL
-  # LIBARCH is used to preserve the jre/lib/i386 directory name for 32-bit intel
-  ARCH=i586
-  LIBARCH=i386
-  # Value of Java os.arch property
-  ARCHPROP=x86
-  REQUIRED_WINDOWS_NAME=Windows Professional 2000
-  REQUIRED_WINDOWS_VERSION=5 0 Service Pack 4
   ifeq ($(ARCH_DATA_MODEL), 64)
     # If the user wants to perform a cross compile build then they must
     # - set ARCH_DATA_MODEL=64 and either
     #      + set ARCH to ia64 or amd64, or
-    REQUIRED_WINDOWS_NAME=Windows Server 2003
-    REQUIRED_WINDOWS_VERSION=5 2 Service Pack 1
+    REQUIRED_WINDOWS_VERSION=Server 2003 Enterprise x64 Edition
     ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)), AMD64)
       ARCH=amd64
     else
@@ -336,6 +327,14 @@
     LIBARCH=$(ARCH)
     # Value of Java os.arch property
     ARCHPROP=$(LIBARCH)
+  else
+    REQUIRED_WINDOWS_VERSION=2000 or Unknown
+    #REQUIRED_WINDOWS_VERSION=XP Professional
+    # LIBARCH is used to preserve the jre/lib/i386 directory name for 32-bit intel
+    ARCH=i586
+    LIBARCH=i386
+    # Value of Java os.arch property
+    ARCHPROP=x86
   endif
   ARCH_FAMILY = $(ARCH)
   # Where is unwanted output to be delivered?
--- a/jdk/make/common/shared/Sanity.gmk	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/common/shared/Sanity.gmk	Thu Jul 10 00:00:00 2008 +0200
@@ -82,15 +82,16 @@
 endif
 
 ifeq ($(PLATFORM), windows)
-  WINVER=$(JDK_TOPDIR)/make/tools/winver/bin/winver.exe
   FREE_SPACE := $(shell $(DF) -kP $(OUTPUTDIR) | $(TAIL) -1 | $(NAWK) '{print $$4;}')
   TEMP_FREE_SPACE := $(shell $(DF) -kP $(TEMP_DISK) | $(TAIL) -1 | $(NAWK) '{print $$4;}')
-  WINDOWS_VERSION := $(shell \
-      if [ -x $(WINVER) ]; then \
-	$(WINVER) ; \
-      else \
-	$(ECHO) "Unknown Windows Version"; \
-      fi)
+  # Localized systeminfo has localized labels, but not localized values.
+  _WINDOWS_VERSION := \
+    $(shell systeminfo 2> $(DEV_NULL) | grep 'Microsoft' | grep 'Windows' | \
+	 cut -d':' -f2)
+  ifeq ($(_WINDOWS_VERSION),)
+    _WINDOWS_VERSION := Windows 2000 or Unknown (no systeminfo utility)
+  endif
+  WINDOWS_VERSION := $(strip $(_WINDOWS_VERSION))
   DXSDK_VER := $(shell $(EGREP) DIRECTDRAW_VERSION $(DXSDK_INCLUDE_PATH)/ddraw.h 2>&1 | \
     $(EGREP) "\#define" | $(NAWK) '{print $$3}')
 endif
@@ -257,9 +258,9 @@
 	    "" >> $(WARNING_FILE) ; \
 	fi
   ifeq ($(PLATFORM), windows)
-	@if [ "$(WINDOWS_VERSION)" != "$(REQUIRED_WINDOWS_VERSION)" ]; then \
-	    $(ECHO) "WARNING: $(YOU_ARE_USING) an unsupported version of $(REQUIRED_WINDOWS_NAME). \n" \
-	      "        The supported version is $(REQUIRED_WINDOWS_NAME) $(REQUIRED_WINDOWS_VERSION). \n" \
+	@if [ "$(findstring $(REQUIRED_WINDOWS_VERSION),$(WINDOWS_VERSION))" = "" ]; then \
+	    $(ECHO) "WARNING: $(YOU_ARE_USING) an unknown version of Windows. \n" \
+	      "        The required version is $(REQUIRED_WINDOWS_VERSION). \n" \
 	      "        $(YOU_ARE_USING) $(WINDOWS_VERSION) \n" \
 	      "" >> $(WARNING_FILE) ; \
 	fi
--- a/jdk/make/java/java/Makefile	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/java/java/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -394,7 +394,7 @@
 $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java: \
 	$(SHARE_SRC)/classes/sun/util/CoreResourceBundleControl-XLocales.java $(LOCALES_GEN_SH)
 	@$(prep-target) 
-	NAWK=$(NAWK) SED=$(SED) $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \
+	NAWK="$(NAWK)" SED="$(SED)" $(SH) $(LOCALES_GEN_SH) "$(JRE_NONEXIST_LOCALES)" \
 		$< $@ 
 clean::
 	$(RM) $(GENSRCDIR)/sun/util/CoreResourceBundleControl.java
--- a/jdk/make/java/nio/Makefile	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/java/nio/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -191,8 +191,8 @@
 
 GEN_BUFFER_SH = genBuffer.sh
 
-GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK=$(NAWK) SED=$(SED) \
-                 $(SH) $(GEN_BUFFER_SH)
+GEN_BUFFER_CMD = SPP="$(SPP_CMD)" NAWK="$(NAWK)" SED="$(SED)" \
+                 SH="$(SH)" $(SH) $(GEN_BUFFER_SH)
 
 # Public abstract buffer classes
 #
@@ -582,7 +582,7 @@
 
 GEN_CODER_SH = genCoder.sh
 
-GEN_CODER_CMD = SPP="$(SPP_CMD)" SED=$(SED) NAWK=$(NAWK) $(SH) $(GEN_CODER_SH)
+GEN_CODER_CMD = SPP="$(SPP_CMD)" SED="$(SED)" NAWK="$(NAWK)" SH="$(SH)" $(SH) $(GEN_CODER_SH)
 
 $(CS_GEN)/CharsetDecoder.java: $(CS_SRC)/Charset-X-Coder.java $(GEN_CODER_SH)
 	$(prep-target)
@@ -602,7 +602,7 @@
 
 GEN_EX_SH = genExceptions.sh
 
-GEN_EX_CMD = NAWK=$(NAWK) SH=$(SH) $(SH) $(GEN_EX_SH)
+GEN_EX_CMD = NAWK="$(NAWK)" SH="$(SH)" $(SH) $(GEN_EX_SH)
 
 $(CH_GEN)/%Exception.java: genExceptions.sh $(CH_SRC)/exceptions
 	$(prep-target)
@@ -635,8 +635,8 @@
     $(HASHER_JARFILE) $(SCS_SRC)/standard-charsets
 	$(prep-target)
 	@$(RM) $@.temp
-	NAWK=$(NAWK) TEMPDIR=$(TEMPDIR) \
+	NAWK="$(NAWK)" TEMPDIR="$(TEMPDIR)" \
 	  HASHER="$(BOOT_JAVA_CMD) -jar $(HASHER_JARFILE)" \
-	  SH=$(SH) $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
+	  SH="$(SH)" $(SH) -e genCharsetProvider.sh $(SCS_SRC)/standard-charsets $(SCS_GEN)
 
 .PHONY: sources
--- a/jdk/make/tools/Makefile	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/make/tools/Makefile	Thu Jul 10 00:00:00 2008 +0200
@@ -32,7 +32,6 @@
 
 SUBDIRS =                   \
   addjsum                   \
-  auto_multi                \
   buildmetaindex            \
   commentchecker            \
   compile_font_config       \
@@ -49,8 +48,7 @@
   javazic                   \
   jdwpgen                   \
   makeclasslist             \
-  strip_properties          \
-  winver
+  strip_properties
 
 all build clean clobber::
 	$(SUBDIRS-loop)
--- a/jdk/make/tools/auto_multi/Makefile	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-#
-# Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-#
-# Makefile for building the automulti tool
-#
-
-BUILDDIR = ../..
-PACKAGE = build.tools.automulti
-PRODUCT = tools
-PROGRAM = automulti
-include $(BUILDDIR)/common/Defs.gmk
-
-BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
-BUILDTOOL_MAIN        = $(PKGDIR)/AutoMulti.java
-
-#
-# Build tool jar rules.
-#
-include $(BUILDDIR)/common/BuildToolJar.gmk
-
--- a/jdk/make/tools/src/build/tools/automulti/AutoMulti.java	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,458 +0,0 @@
-/*
- * Copyright 1998-2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package build.tools.automulti;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-
-/**
- * Automatically generates the Multiplexing UI classes
- * for Swing.
- * <p>
- * To use, type 'java AutoMulti <plafdir> <prefix>' where <plafdir>
- * is the directory containing the source for Swing's UI classes and
- * <prefix> is the package prefix to use before ".swing.plaf.multi".
- * For example:
- *
- * <pre>
- * cd TEST
- * ../../../../build/solaris-sparc/bin/java AutoMulti ../../../../src/share/classes/javax/swing/plaf javax
- * </pre>
- *
- * AutoMulti will scour the plaf directory for *UI.java files and
- * generate Multi*UI.java files that do the multiplexing thing.
- * <p>
- * NOTE:  This tool depends upon the existence of <plafdir> and on the
- * compiled classes from <plafdir> being somewhere in the class path.
- *
- * @author Willie Walker
- */
-public class AutoMulti {
-    static String importLines;
-
-    /**
-     * A silly list of parameter names to use.  Skips "i" because we use
-     * it as a 'for' loop counter.  If you want to get fancy, please feel
-     * to change how parameter names are obtained.  This will break if
-     * someone decides to create a UI method that takes more than 8
-     * parameters.  Which one is a bug (this breaking or having a method
-     * with more than eight parameters) is a subjective thing.
-     */
-    public static String[] paramNames = {"a","b","c","d","e","f","g","h"};
-
-    /**
-     * Removes the package names (e.g., javax.swing) from the name.
-     */
-    public static String unqualifyName(String name) {
-        StringTokenizer parser = new StringTokenizer(name,".");
-        String unqualifiedName = null;
-        while (parser.hasMoreTokens()) {
-            unqualifiedName = parser.nextToken();
-        }
-        return removeDollars(unqualifiedName);
-    }
-
-    /**
-     * Strips the extension from the filename.
-     */
-    public static String stripExtension(String name) {
-        StringTokenizer parser = new StringTokenizer(name,".");
-        return parser.nextToken();
-    }
-
-    /**
-     * Adds some spaces.
-     */
-    public static void indent(StringBuffer s, int i) {
-        while (i > 0) {
-            s.append(" ");
-            i--;
-        }
-    }
-
-    /**
-     * Spits out all the beginning stuff.
-     */
-    public static StringBuffer createPreamble(String prefixName) {
-        StringBuffer s = new StringBuffer();
-        s.append("/*\n");
-        s.append(" *\n");
-        s.append(" * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.\n");
-        s.append(" * \n");
-        s.append(" * This software is the proprietary information of Sun Microsystems, Inc.  \n");
-        s.append(" * Use is subject to license terms.\n");
-        s.append(" * \n");
-        s.append(" */\n");
-        s.append("package " + prefixName + ".swing.plaf.multi;\n");
-        s.append("\n");
-        return s;
-    }
-
-    /**
-     * Replaces 'Xxx$Yyy' with "Xxx'.  Used by addImport because you
-     * can't import nested classes directly.
-     */
-    public static String removeNestedClassName(String s) {
-        int dollarPosition = s.indexOf('$');
-
-        if (dollarPosition >= 0) {    // s contains '$'
-            StringBuffer sb = new StringBuffer(s);
-            sb.setLength(dollarPosition);
-            return sb.toString();
-        } else {                      // no '$'
-            return s;
-        }
-    }
-
-    /**
-     * Replaces '$' with ".'.  Needed for printing inner class names
-     * for argument and return types.
-     */
-    public static String removeDollars(String s) {
-        int dollarPosition = s.indexOf('$');
-
-        if (dollarPosition >= 0) {    // s contains '$'
-            StringBuffer sb = new StringBuffer(s);
-            while (dollarPosition >= 0) {
-                //XXX: will there ever be more than one '$'?
-                sb.replace(dollarPosition, dollarPosition+1, ".");
-                dollarPosition = sb.indexOf("$", dollarPosition);
-            }
-            return sb.toString();
-        } else {                     // no $
-            return s;
-        }
-    }
-
-    /**
-     * Adds an import line to the String.
-     */
-    public static void addImport(String s, Class theClass) {
-        if (!theClass.isPrimitive() && (theClass != Object.class)) {
-            String className = removeNestedClassName(theClass.getName());
-            String importLine = new String("import " + className + ";\n");
-            if (importLines.indexOf(importLine) == -1) {
-                importLines += importLine;
-            }
-        }
-    }
-
-    /**
-     * Spits out the class header information.
-     */
-    public static void addHeader(StringBuffer s, String className) {
-        s.append("/**\n");
-        s.append(" * A multiplexing UI used to combine <code>" + className + "</code>s.\n");
-        s.append(" * \n");
-        s.append(" * <p>This file was automatically generated by AutoMulti.\n");
-        s.append(" *\n");
-        s.append(" * @author  Otto Multey\n");                  // Get it?  I crack myself up.
-        s.append(" */\n");
-        s.append("public class Multi" + className + " extends " + className + " {\n");
-        s.append("\n");
-        s.append("    /**\n");
-        s.append("     * The vector containing the real UIs.  This is populated \n");
-        s.append("     * in the call to <code>createUI</code>, and can be obtained by calling\n");
-        s.append("     * the <code>getUIs</code> method.  The first element is guaranteed to be the real UI \n");
-        s.append("     * obtained from the default look and feel.\n");
-        s.append("     */\n");
-        s.append("    protected Vector uis = new Vector();\n");
-        s.append("\n");
-        s.append("////////////////////\n");
-        s.append("// Common UI methods\n");
-        s.append("////////////////////\n");
-        s.append("\n");
-        s.append("    /**\n");
-        s.append("     * Returns the list of UIs associated with this multiplexing UI.  This \n");
-        s.append("     * allows processing of the UIs by an application aware of multiplexing \n");
-        s.append("     * UIs on components.\n");
-        s.append("     */\n");
-        s.append("    public ComponentUI[] getUIs() {\n");
-        s.append("        return MultiLookAndFeel.uisToArray(uis);\n");
-        s.append("    }\n");
-    }
-
-    /**
-     * Prints out the code for a method.  This is pretty specific to the
-     * Multiplexing UI code, so don't get any fancy ideas.
-     */
-    public static void addMethod(StringBuffer s, Method m, String origName, String className) {
-
-        // Get the method name and the return type.  Be a little careful about arrays.
-        //
-        String methodName = unqualifyName(m.getName());
-        String returnType;
-        if (!m.getReturnType().isArray()) {
-            returnType = unqualifyName(m.getReturnType().toString());
-            addImport(importLines,m.getReturnType());
-        } else {
-            returnType = unqualifyName(m.getReturnType().getComponentType().toString())
-                         + "[]";
-            addImport(importLines,m.getReturnType().getComponentType());
-        }
-
-        // Print the javadoc
-        //
-        s.append("\n");
-        if (methodName.equals("createUI")) {
-            s.append("    /**\n");
-            s.append("     * Returns a multiplexing UI instance if any of the auxiliary\n");
-            s.append("     * <code>LookAndFeel</code>s supports this UI.  Otherwise, just returns the \n");
-            s.append("     * UI object obtained from the default <code>LookAndFeel</code>.\n");
-            s.append("     */\n");
-        } else if (!returnType.equals("void")) {
-            s.append("    /**\n");
-            s.append("     * Invokes the <code>" + methodName + "</code> method on each UI handled by this object.\n");
-            s.append("     * \n");
-            s.append("     * @return the value obtained from the first UI, which is\n");
-            s.append("     * the UI obtained from the default <code>LookAndFeel</code>\n");
-            s.append("     */\n");
-        } else {
-            s.append("    /**\n");
-            s.append("     * Invokes the <code>" + methodName
-                     + "</code> method on each UI handled by this object.\n");
-            s.append("     */\n");
-        }
-
-        // Print the method signature
-        //
-        s.append("    public");
-        if (Modifier.isStatic(m.getModifiers())) {
-            s.append(" static");
-        }
-        s.append(" " + returnType);
-        s.append(" " + methodName);
-        s.append("(");
-
-        Class[] params = m.getParameterTypes();
-        Class temp;
-        String braces;
-        for (int i = 0; i < params.length; i++) {
-            if (i > 0) {
-                s.append(", ");
-            }
-            temp = params[i];
-            braces = new String("");
-            while (temp.isArray()) {
-                braces += "[]";
-                temp = temp.getComponentType();
-            }
-            s.append(unqualifyName(temp.getName()) + braces + " " + paramNames[i]);
-            addImport(importLines,temp);
-        }
-        s.append(")");
-
-        // Don't forget about exceptions
-        //
-        Class exceptions[] = m.getExceptionTypes();
-        String throwsString = new String("");
-
-        if (exceptions.length > 0) {
-            s.append("\n");
-            indent(s,12);
-            s.append("throws ");
-            for (int i = 0; i < exceptions.length; i++) {
-                if (i > 0) {
-                    s.append(", ");
-                }
-                s.append(unqualifyName(exceptions[i].getName()));
-                addImport(importLines,exceptions[i]);
-            }
-        }
-        s.append(throwsString + " {\n");
-
-        // Now print out the contents of the method.  We do a special thing
-        // for the createUI method, another thing if the method returns 'void'
-        // and a third thing if we don't do either of the first two.  If
-        // you want to squash this down, feel free.
-        //
-        if (methodName.equals("createUI")) {
-            indent(s,8);
-            s.append("ComponentUI mui = new Multi" + origName + "();\n");
-            indent(s,8);
-            s.append("return MultiLookAndFeel.createUIs(mui,\n");
-            indent(s,42);
-            s.append("((Multi" + origName +") mui).uis,\n");
-            indent(s,42);
-            for (int i = 0; i < params.length; i++) {
-                if (i > 0) {
-                    s.append(",");
-                }
-                s.append(paramNames[i]);
-            }
-            s.append(");\n");
-        } else if (!returnType.equals("void")) {
-            indent(s,8);
-            s.append(returnType + " returnValue = \n");
-            indent(s,12);
-            s.append("((" + className + ") (uis.elementAt(0)))."
-                     + methodName + "(");
-            for (int i = 0; i < params.length; i++) {
-                if (i > 0) {
-                    s.append(",");
-                }
-                s.append(paramNames[i]);
-            }
-            s.append(");\n");
-            indent(s,8);
-            s.append("for (int i = 1; i < uis.size(); i++) {\n");
-            indent(s,12);
-            s.append("((" + className + ") (uis.elementAt(i)))."
-                     + methodName + "(");
-            for (int i = 0; i < params.length; i++) {
-                if (i > 0) {
-                    s.append(",");
-                }
-                s.append(paramNames[i]);
-            }
-            s.append(");\n");
-            indent(s,8);
-            s.append("}\n");
-            indent(s,8);
-            s.append("return returnValue;\n");
-        } else {
-            indent(s,8);
-            s.append("for (int i = 0; i < uis.size(); i++) {\n");
-            indent(s,12);
-            s.append("((" + className + ") (uis.elementAt(i)))."
-                     + methodName + "(");
-            for (int i = 0; i < params.length; i++) {
-                if (i > 0) {
-                    s.append(",");
-                }
-                s.append(paramNames[i]);
-            }
-            s.append(");\n");
-            indent(s,8);
-            s.append("}\n");
-        }
-        indent(s,4);
-        s.append("}\n");
-    }
-
-    /**
-     * Takes a plaf class name (e.g., "MenuUI") and generates the corresponding
-     * Multiplexing UI Java source code (e.g., "MultiMenuUI.java").
-     */
-    public static void generateFile(String prefixName, String className) {
-        try {
-            FileOutputStream fos;
-            PrintWriter outFile;
-
-            importLines = new String();
-            importLines += new String("import java.util.Vector;\n");
-
-            StringBuffer body = new StringBuffer();
-            Class wee = Class.forName(prefixName + ".swing.plaf." + className);
-            String weeName = unqualifyName(wee.getName());
-            addImport(importLines,wee);
-            while (!weeName.equals("Object")) {
-                body.append("\n");
-                body.append("////////////////////\n");
-                body.append("// " + weeName + " methods\n");
-                body.append("////////////////////\n");
-                Method[] methods = wee.getDeclaredMethods();
-                for (int i=0; i < methods.length; i++) {
-                    if (Modifier.isPublic(methods[i].getModifiers())) {
-                        addMethod(body,methods[i],className,weeName);
-                    }
-                }
-                wee = wee.getSuperclass();
-                weeName = unqualifyName(wee.getName());
-                addImport(importLines,wee);
-            }
-
-            fos = new FileOutputStream("Multi" + className + ".java");
-            outFile = new PrintWriter(fos);
-            StringBuffer outText = createPreamble(prefixName);
-            outText.append(importLines.toString() + "\n");
-            addHeader(outText,className);
-            outText.append(body.toString());
-            outText.append("}\n");
-            outFile.write(outText.toString());
-            outFile.flush();
-            outFile.close();
-        } catch (Exception e) {
-            System.err.println(e);
-        }
-    }
-
-    /**
-     * D'Oh!  Something bad happened.
-     */
-    public static void usage(String s) throws IOException {
-        System.err.println("Usage:  AutoMulti <plafdir> [com.sun]");
-        throw new IllegalArgumentException(s);
-    }
-
-    /**
-     * Takes the plaf directory name and generates the multiplexing UI
-     * source code.
-     */
-    public static void main(String[] args) throws IOException {
-
-        if (args.length < 1) {
-            usage("");
-        }
-
-        String dirName = args[0];
-        File dir = new File(dirName);
-        if (!dir.isDirectory()) {
-            System.err.println("No such directory:  " + dirName);
-            usage("");
-        }
-
-        String prefixName;
-        if (args.length > 1) {
-            prefixName = args[1];
-        } else {
-            prefixName = "com.sun.java";
-        }
-
-        String plafUIs[] = dir.list(new UIJavaFilter());
-        for (int i = 0; i < plafUIs.length; i++) {
-            generateFile(prefixName,stripExtension(plafUIs[i]));
-        }
-    }
-}
-
-/**
- * Only accepts file names of the form *UI.java.  The one exception
- * is not accepting ComponentUI.java because we don't need to generate
- * a multiplexing class for it.
- */
-class UIJavaFilter implements FilenameFilter {
-    public boolean accept(File dir, String name) {
-        if (name.equals("ComponentUI.java")) {
-            return false;
-        } else if (name.endsWith("UI.java")) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-}
--- a/jdk/make/tools/src/build/tools/automulti/README.txt	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-AutoMulti is the tool that automatically generates the
-Multi*UI classes for the Multiplexing look and feel. 
-Instructions for using it are in AutoMulti.java.
-
-TestALFGenerator is a tool (a variation of AutoMulti)
-that automatically generates an auxiliary look and
-feel that you can use to test the Multiplexing look
-and feel.  The TestALF look and feel implements every
-method by printing the message "In the xxx method of
-the TextALFYyyUI class." and, except in the case of
-createUI, returning something meaningless (since,
-except in the case of createUI, the return value is
-ignored).  
-
-TestALFLookAndFeel.java is the only non-auto-generated
-file for the TestALF L&F.  If you specify a package
-argument to TestALFGenerator, you'll have to change
-the code in TestALFLookAndFeel.java to reflect the
-package name.
-
-To test any application with the TestALF, make sure the
-compiled TestALF classes are in the class path.  Then add
-this to the <JDK_HOME>/lib/swing.properties file (which
-you'll probably have to create):
-
-swing.auxiliarylaf=TestALFLookAndFeel
-
-E.g., if you're running SwingSet2 against your solaris
-build, then you'd create/edit the swing.properties file
-in <wsdir>/build/solaris-sparc/lib.
-
-Then run any app.  You'll see lots of thrilling "In the
-Xxxx method of the Yyy class" messages.  If you get anything
-else (especially an exception), then you've found a bug.
-Probably in the default look and feel.
-
--- a/jdk/make/tools/src/build/tools/automulti/TestALFGenerator.java	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,401 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package build.tools.automulti;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.io.*;
-
-/**
- * Automatically generates an auxiliary look and feel to be
- * used for testing the Multiplexing look and feel.
- * <p>
- * To use, type 'java TestALFGenerator <plafdir> [<package>]' where <plafdir>
- * is the directory containing the source for Swing's UI classes.
- * <package> is an optional argument that specifies the package
- * of the TestALF classes.  If it's omitted, the classes are in
- * the default package.
- * For example:
- *
- * <pre>
- * ../../../../build/solaris-sparc/bin/java TestALFGenerator ../../../../src/share/classes/javax/swing/plaf com.myco.myalaf
- * </pre>
- *
- * TestALFGenerator will scour the plaf directory for *UI.java files and
- * generate TestALF*UI.java files.
- * <p>
- * NOTE:  This tool depends upon the existence of <plafdir> and on the
- * compiled classes from <plafdir> being somewhere in the class path.
- *
- * @author Willie Walker
- */
-public class TestALFGenerator {
-    static String importLines;
-    static String packageName;
-    static String classPrefix = "TestALF";
-
-    /**
-     * A silly list of parameter names to use.  Skips "i" because we use
-     * it as a 'for' loop counter.  If you want to get fancy, please feel
-     * to change how parameter names are obtained.  This will break if
-     * someone decides to create a UI method that takes more than 8
-     * parameters.  Which one is a bug (this breaking or having a method
-     * with more than eight parameters) is a subjective thing.
-     */
-    public static String[] paramNames = {"a","b","c","d","e","f","g","h"};
-
-    /**
-     * Removes the package names (e.g., javax.swing) from the name.
-     */
-    public static String unqualifyName(String name) {
-        StringTokenizer parser = new StringTokenizer(name,".");
-        String unqualifiedName = null;
-        while (parser.hasMoreTokens()) {
-            unqualifiedName = parser.nextToken();
-        }
-        return removeDollars(unqualifiedName);
-    }
-
-    /**
-     * Strips the extension from the filename.
-     */
-    public static String stripExtension(String name) {
-        StringTokenizer parser = new StringTokenizer(name,".");
-        return parser.nextToken();
-    }
-
-    /**
-     * Adds some spaces.
-     */
-    public static void indent(StringBuffer s, int i) {
-        while (i > 0) {
-            s.append(" ");
-            i--;
-        }
-    }
-
-    /**
-     * Spits out all the beginning stuff.
-     */
-    public static StringBuffer createPreamble(String prefixName) {
-        StringBuffer s = new StringBuffer();
-        s.append("/*\n");
-        s.append(" *\n");
-        s.append(" * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.\n");
-        s.append(" * \n");
-        s.append(" * This software is the proprietary information of Sun Microsystems, Inc.  \n");
-        s.append(" * Use is subject to license terms.\n");
-        s.append(" * \n");
-        s.append(" */\n");
-        if (packageName != null) {
-            s.append("package " + packageName + ";\n");
-            s.append("\n");
-        }
-        return s;
-    }
-
-    /**
-     * Replaces 'Xxx$Yyy' with "Xxx'.  Used by addImport because you
-     * can't import nested classes directly.
-     */
-    public static String removeNestedClassName(String s) {
-        int dollarPosition = s.indexOf('$');
-
-        if (dollarPosition >= 0) {    // s contains '$'
-            StringBuffer sb = new StringBuffer(s);
-            sb.setLength(dollarPosition);
-            return sb.toString();
-        } else {                      // no '$'
-            return s;
-        }
-    }
-
-    /**
-     * Replaces '$' with ".'.  Needed for printing inner class names
-     * for argument and return types.
-     */
-    public static String removeDollars(String s) {
-        int dollarPosition = s.indexOf('$');
-
-        if (dollarPosition >= 0) {    // s contains '$'
-            StringBuffer sb = new StringBuffer(s);
-            while (dollarPosition >= 0) {
-                //XXX: will there ever be more than one '$'?
-                sb.replace(dollarPosition, dollarPosition+1, ".");
-                dollarPosition = sb.indexOf("$", dollarPosition);
-            }
-            return sb.toString();
-        } else {                     // no $
-            return s;
-        }
-    }
-
-    /**
-     * Adds an import line to the String.
-     */
-    public static void addImport(String s, Class theClass) {
-        if (!theClass.isPrimitive() && (theClass != Object.class)) {
-            String className = removeNestedClassName(theClass.getName());
-            String importLine = new String("import " + className + ";\n");
-            if (importLines.indexOf(importLine) == -1) {
-                importLines += importLine;
-            }
-        }
-    }
-
-    /**
-     * Spits out the class header information.
-     */
-    public static void addHeader(StringBuffer s, String className) {
-        s.append("/**\n");
-        s.append(" * An auxiliary UI for <code>" + className + "</code>s.\n");
-        s.append(" * \n");
-        s.append(" * <p>This file was automatically generated by TestALFGenerator.\n");
-        s.append(" *\n");
-        s.append(" * @author  Otto Multey\n");                  // Get it?  I crack myself up.
-        s.append(" */\n");
-        s.append("public class " + classPrefix + className + " extends " + className + " {\n");
-        s.append("\n");
-    }
-
-    /**
-     * Prints out the code for a method.
-     */
-    public static void addMethod(StringBuffer s, Method m, String origName, String className) {
-
-        // Get the method name and the return type.  Be a little careful about arrays.
-        //
-        String methodName = unqualifyName(m.getName());
-        String returnType;
-
-        if (!m.getReturnType().isArray()) {
-            returnType = unqualifyName(m.getReturnType().toString());
-            addImport(importLines,m.getReturnType());
-        } else {
-            returnType = unqualifyName(m.getReturnType().getComponentType().toString())
-                         + "[]";
-            addImport(importLines,m.getReturnType().getComponentType());
-        }
-
-        // Print the javadoc
-        //
-        s.append("\n");
-
-        if (methodName.equals("createUI")) {
-            s.append("    /**\n");
-            s.append("     * Returns a UI object for this component.\n");
-            s.append("     */\n");
-        } else {
-            s.append("    /**\n");
-            s.append("     * Prints a message saying this method has been invoked.\n");
-            s.append("     */\n");
-        }
-
-        // Print the method signature
-        //
-        s.append("    public");
-        if (Modifier.isStatic(m.getModifiers())) {
-            s.append(" static");
-        }
-        s.append(" " + returnType);
-        s.append(" " + methodName);
-        s.append("(");
-
-        Class[] params = m.getParameterTypes();
-        Class temp;
-        String braces;
-        for (int i = 0; i < params.length; i++) {
-            if (i > 0) {
-                s.append(", ");
-            }
-            temp = params[i];
-            braces = new String("");
-            while (temp.isArray()) {
-                braces += "[]";
-                temp = temp.getComponentType();
-            }
-            s.append(unqualifyName(temp.getName()) + braces + " " + paramNames[i]);
-            addImport(importLines,temp);
-        }
-        s.append(")");
-
-        // Don't forget about exceptions
-        //
-        Class exceptions[] = m.getExceptionTypes();
-        String throwsString = new String("");
-
-        if (exceptions.length > 0) {
-            s.append("\n");
-            indent(s,12);
-            s.append("throws ");
-            for (int i = 0; i < exceptions.length; i++) {
-                if (i > 0) {
-                    s.append(", ");
-                }
-                s.append(unqualifyName(exceptions[i].getName()));
-                addImport(importLines,exceptions[i]);
-            }
-        }
-        s.append(throwsString + " {\n");
-
-        // Now print out the contents of the method.
-        indent(s,8);
-        s.append("System.out.println(\"In the " + methodName
-                                    + " method of the "
-                                    + classPrefix + origName + " class.\");\n");
-        if (methodName.equals("createUI")) {
-            indent(s,8);
-            s.append("return ui;\n");
-        } else {
-            // If we have to return something, do so.
-            if (!returnType.equals("void")) {
-                Class rType = m.getReturnType();
-                indent(s,8);
-                if (!rType.isPrimitive()) {
-                    s.append("return null;\n");
-                } else if (rType == Boolean.TYPE) {
-                    s.append("return false;\n");
-                } else if (rType == Character.TYPE) {
-                    s.append("return '0';\n");
-                } else {  // byte, short, int, long, float, or double
-                    s.append("return 0;\n");
-                }
-            }
-        }
-
-        indent(s,4);
-        s.append("}\n");
-    }
-
-    /**
-     * Takes a plaf class name (e.g., "MenuUI") and generates the corresponding
-     * TestALF UI Java source code (e.g., "TestALFMenuUI.java").
-     */
-    public static void generateFile(String prefixName, String className) {
-        try {
-            FileOutputStream fos;
-            PrintWriter outFile;
-
-            importLines = new String();
-            importLines += new String("import java.util.Vector;\n");
-
-            StringBuffer body = new StringBuffer();
-            Class wee = Class.forName(prefixName + ".swing.plaf." + className);
-            String weeName = unqualifyName(wee.getName());
-            String thisClassName = classPrefix + className;
-            addImport(importLines,wee);
-
-            // Declare and initialize the shared UI object.
-            body.append("\n");
-            body.append("////////////////////\n");
-            body.append("// Shared UI object\n");
-            body.append("////////////////////\n");
-            body.append("private final static " + thisClassName
-                        + " ui = new " + thisClassName + "();\n");
-
-            while (!weeName.equals("Object")) {
-                body.append("\n");
-                body.append("////////////////////\n");
-                body.append("// " + weeName + " methods\n");
-                body.append("////////////////////\n");
-                Method[] methods = wee.getDeclaredMethods();
-                for (int i=0; i < methods.length; i++) {
-                    if (Modifier.isPublic(methods[i].getModifiers())) {
-                        addMethod(body,methods[i],className,weeName);
-                    }
-                }
-                wee = wee.getSuperclass();
-                weeName = unqualifyName(wee.getName());
-                addImport(importLines,wee);
-            }
-
-            fos = new FileOutputStream(classPrefix + className + ".java");
-            outFile = new PrintWriter(fos);
-            StringBuffer outText = createPreamble(prefixName);
-            outText.append(importLines.toString() + "\n");
-            addHeader(outText,className);
-            outText.append(body.toString());
-            outText.append("}\n");
-            outFile.write(outText.toString());
-            outFile.flush();
-            outFile.close();
-        } catch (Exception e) {
-            System.err.println(e);
-        }
-    }
-
-    /**
-     * D'Oh!  Something bad happened.
-     */
-    public static void usage(String s) throws IOException {
-        System.err.println("Usage:  java TestALFGenerator <plafdir> [<packageName>]");
-        throw new IllegalArgumentException(s);
-    }
-
-    /**
-     * Takes the plaf directory name and generates the TestALF UI
-     * source code.
-     */
-    public static void main(String[] args) throws IOException {
-
-        if (args.length < 1) {
-            usage("");
-        }
-
-        String dirName = args[0];
-        File dir = new File(dirName);
-        if (!dir.isDirectory()) {
-            System.err.println("No such directory:  " + dirName);
-            usage("");
-        }
-
-        if (args.length > 1) {
-            packageName = args[1];
-        }
-
-        String plafUIs[] = dir.list(new UIJavaFilter());
-        for (int i = 0; i < plafUIs.length; i++) {
-            generateFile("javax",stripExtension(plafUIs[i]));
-        }
-    }
-}
-
-/**
- * Only accepts file names of the form *UI.java.  The one exception
- * is not accepting ComponentUI.java because we don't need to generate
- * a TestALF class for it.
- */
-class UIJavaFilter implements FilenameFilter {
-    public boolean accept(File dir, String name) {
-        if (name.equals("ComponentUI.java")) {
-            return false;
-        } else if (name.endsWith("UI.java")) {
-            return true;
-        } else {
-            return false;
-        }
-    }
-}
--- a/jdk/make/tools/src/build/tools/automulti/TestALFLookAndFeel.java	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-//package com.myco.myalaf;  //search for myalaf for other refs to package name
-
-
-package build.tools.automulti;
-
-import java.util.Vector;
-import java.lang.reflect.Method;
-import javax.swing.*;
-import javax.swing.plaf.*;
-
-/**
- * <p>An auxiliary look and feel used for testing the Multiplexing
- * look and feel.
- * <p>
- *
- * @see UIManager#addAuxiliaryLookAndFeel
- * @see javax.swing.plaf.multi
- *
- * @author Kathy Walrath
- * @author Will Walker
- */
-public class TestALFLookAndFeel extends LookAndFeel {
-
-//////////////////////////////
-// LookAndFeel methods
-//////////////////////////////
-
-    /**
-     * Returns a string, suitable for use in menus,
-     * that identifies this look and feel.
-     *
-     * @return a string such as "Test Auxiliary Look and Feel"
-     */
-    public String getName() {
-        return "Test Auxiliary Look and Feel";
-    }
-
-    /**
-     * Returns a string, suitable for use by applications/services,
-     * that identifies this look and feel.
-     *
-     * @return "TestALF"
-     */
-    public String getID() {
-        return "TestALF";
-    }
-
-    /**
-     * Returns a one-line description of this look and feel.
-     *
-     * @return a descriptive string such as "Allows multiple UI instances per component instance"
-     */
-    public String getDescription() {
-        return "Allows multiple UI instances per component instance";
-    }
-
-    /**
-     * Returns <code>false</code>;
-     * this look and feel is not native to any platform.
-     *
-     * @return <code>false</code>
-     */
-    public boolean isNativeLookAndFeel() {
-        return false;
-    }
-
-    /**
-     * Returns <code>true</code>;
-     * every platform permits this look and feel.
-     *
-     * @return <code>true</code>
-     */
-    public boolean isSupportedLookAndFeel() {
-        return true;
-    }
-
-    /**
-     * Creates, initializes, and returns
-     * the look and feel specific defaults.
-     * For this look and feel,
-     * the defaults consist solely of
-     * mappings of UI class IDs
-     * (such as "ButtonUI")
-     * to <code>ComponentUI</code> class names
-     * (such as "com.myco.myalaf.MultiButtonUI").
-     *
-     * @return an initialized <code>UIDefaults</code> object
-     * @see javax.swing.JComponent#getUIClassID
-     */
-    public UIDefaults getDefaults() {
-        System.out.println("In the TestALFLookAndFeel getDefaults method.");
-        UIDefaults table = new TestALFUIDefaults();
-        //String prefix = "com.myco.myalaf.TestALF";
-        String prefix = "TestALF";
-        Object[] uiDefaults = {
-                   "ButtonUI", prefix + "ButtonUI",
-         "CheckBoxMenuItemUI", prefix + "MenuItemUI",
-                 "CheckBoxUI", prefix + "ButtonUI",
-             "ColorChooserUI", prefix + "ColorChooserUI",
-                 "ComboBoxUI", prefix + "ComboBoxUI",
-              "DesktopIconUI", prefix + "DesktopIconUI",
-              "DesktopPaneUI", prefix + "DesktopPaneUI",
-               "EditorPaneUI", prefix + "TextUI",
-              "FileChooserUI", prefix + "FileChooserUI",
-       "FormattedTextFieldUI", prefix + "TextUI",
-            "InternalFrameUI", prefix + "InternalFrameUI",
-                    "LabelUI", prefix + "LabelUI",
-                     "ListUI", prefix + "ListUI",
-                  "MenuBarUI", prefix + "MenuBarUI",
-                 "MenuItemUI", prefix + "MenuItemUI",
-                     "MenuUI", prefix + "MenuItemUI",
-               "OptionPaneUI", prefix + "OptionPaneUI",
-                    "PanelUI", prefix + "PanelUI",
-            "PasswordFieldUI", prefix + "TextUI",
-       "PopupMenuSeparatorUI", prefix + "SeparatorUI",
-                "PopupMenuUI", prefix + "PopupMenuUI",
-              "ProgressBarUI", prefix + "ProgressBarUI",
-      "RadioButtonMenuItemUI", prefix + "MenuItemUI",
-              "RadioButtonUI", prefix + "ButtonUI",
-                 "RootPaneUI", prefix + "RootPaneUI",
-                "ScrollBarUI", prefix + "ScrollBarUI",
-               "ScrollPaneUI", prefix + "ScrollPaneUI",
-                "SeparatorUI", prefix + "SeparatorUI",
-                   "SliderUI", prefix + "SliderUI",
-                  "SpinnerUI", prefix + "SpinnerUI",
-                "SplitPaneUI", prefix + "SplitPaneUI",
-               "TabbedPaneUI", prefix + "TabbedPaneUI",
-              "TableHeaderUI", prefix + "TableHeaderUI",
-                    "TableUI", prefix + "TableUI",
-                 "TextAreaUI", prefix + "TextUI",
-                "TextFieldUI", prefix + "TextUI",
-                 "TextPaneUI", prefix + "TextUI",
-             "ToggleButtonUI", prefix + "ButtonUI",
-         "ToolBarSeparatorUI", prefix + "SeparatorUI",
-                  "ToolBarUI", prefix + "ToolBarUI",
-                  "ToolTipUI", prefix + "ToolTipUI",
-                     "TreeUI", prefix + "TreeUI",
-                 "ViewportUI", prefix + "ViewportUI",
-        };
-
-        table.putDefaults(uiDefaults);
-        return table;
-    }
-
-}
-
-/**
- * We want the Test auxiliary look and feel to be quiet and fallback
- * gracefully if it cannot find a UI.  This class overrides the
- * getUIError method of UIDefaults, which is the method that
- * emits error messages when it cannot find a UI class in the
- * LAF.
- */
-class TestALFUIDefaults extends UIDefaults {
-    protected void getUIError(String msg) {
-        System.err.println("Test auxiliary L&F:  " + msg);
-    }
-}
--- a/jdk/make/tools/winver/Makefile	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#
-# Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.  Sun designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Sun in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-# CA 95054 USA or visit www.sun.com if you need additional information or
-# have any questions.
-#
-
-#
-# Makefile for building the winver tool
-#
-
-BUILDDIR = ../..
-PRODUCT = tools
-PROGRAM = winver
-include $(BUILDDIR)/common/Defs.gmk
-
-build: permissions
-
-permissions:
-ifeq ($(PLATFORM),windows)
-	$(CHMOD) a+x bin/winver.exe
-endif
-
-#
-# Rules.
-#
-include $(BUILDDIR)/common/Rules.gmk
-
-.PHONY: permissions
-
Binary file jdk/make/tools/winver/bin/winver.exe has changed
--- a/jdk/make/tools/winver/src/StdAfx.cpp	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-// stdafx.cpp : source file that includes just the standard includes
-//      getver.pch will be the pre-compiled header
-//      stdafx.obj will contain the pre-compiled type information
-
-#include "stdafx.h"
-
-// TODO: reference any additional headers you need in STDAFX.H
-// and not in this file
--- a/jdk/make/tools/winver/src/StdAfx.h	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-// stdafx.h : include file for standard system include files,
-//  or project specific include files that are used frequently, but
-//      are changed infrequently
-//
-
-#if !defined(AFX_STDAFX_H__C592D6C3_027D_11D5_8DFB_080020C19238__INCLUDED_)
-#define AFX_STDAFX_H__C592D6C3_027D_11D5_8DFB_080020C19238__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
-
-#include <stdio.h>
-
-// TODO: reference additional headers your program requires here
-
-//{{AFX_INSERT_LOCATION}}
-// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
-
-#endif // !defined(AFX_STDAFX_H__C592D6C3_027D_11D5_8DFB_080020C19238__INCLUDED_)
--- a/jdk/make/tools/winver/src/winver.cpp	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2001 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-// getver.cpp : Defines the entry point for the console application.
-//
-
-#include "stdafx.h"
-#include <windows.h>
-
-int main(int argc, char* argv[])
-{
-        OSVERSIONINFO verInfo;
-
-        memset(&verInfo,0,sizeof(verInfo));
-        verInfo.dwOSVersionInfoSize = sizeof(verInfo);
-
-        if (GetVersionEx(&verInfo))
-        {
-                printf("%d %d %s",verInfo.dwMajorVersion,verInfo.dwMinorVersion,verInfo.szCSDVersion);
-        }
-        else
-        {
-                printf("No version info available");
-        }
-
-        return 0;
-}
--- a/jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFileSoundbankReader.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,133 +1,133 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.spi.SoundbankReader;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.UnsupportedAudioFileException;
-
-/**
- * Soundbank reader that uses audio files as soundbanks.
- *
- * @author Karl Helgason
- */
-public class AudioFileSoundbankReader extends SoundbankReader {
-
-    public Soundbank getSoundbank(URL url)
-            throws InvalidMidiDataException, IOException {
-        try {
-            AudioInputStream ais = AudioSystem.getAudioInputStream(url);
-            Soundbank sbk = getSoundbank(ais);
-            ais.close();
-            return sbk;
-        } catch (UnsupportedAudioFileException e) {
-            return null;
-        } catch (IOException e) {
-            return null;
-        }
-    }
-
-    public Soundbank getSoundbank(InputStream stream)
-            throws InvalidMidiDataException, IOException {
-        stream.mark(512);
-        try {
-            AudioInputStream ais = AudioSystem.getAudioInputStream(stream);
-            Soundbank sbk = getSoundbank(ais);
-            if (sbk != null)
-                return sbk;
-        } catch (UnsupportedAudioFileException e) {
-        } catch (IOException e) {
-        }
-        stream.reset();
-        return null;
-    }
-
-    public Soundbank getSoundbank(AudioInputStream ais)
-            throws InvalidMidiDataException, IOException {
-        try {
-            try {
-                byte[] buffer;
-                if (ais.getFrameLength() == -1) {
-                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                    byte[] buff = new byte[1024
-                            - (1024 % ais.getFormat().getFrameSize())];
-                    int ret;
-                    while ((ret = ais.read(buff)) != -1) {
-                        baos.write(buff, 0, ret);
-                    }
-                    ais.close();
-                    buffer = baos.toByteArray();
-                } else {
-                    buffer = new byte[(int)(ais.getFrameLength()
-                                        * ais.getFormat().getFrameSize())];
-                    ais.read(buffer);
-                }
-                ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
-                        new ModelByteBuffer(buffer), ais.getFormat(), -4800);
-                ModelPerformer performer = new ModelPerformer();
-                performer.getOscillators().add(osc);
-
-                SimpleSoundbank sbk = new SimpleSoundbank();
-                SimpleInstrument ins = new SimpleInstrument();
-                ins.add(performer);
-                sbk.addInstrument(ins);
-                return sbk;
-            } finally {
-            }
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    public Soundbank getSoundbank(File file)
-            throws InvalidMidiDataException, IOException {
-        try {
-            AudioInputStream ais = AudioSystem.getAudioInputStream(file);
-            ais.close();
-            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
-                    new ModelByteBuffer(file, 0, file.length()), -4800);
-            ModelPerformer performer = new ModelPerformer();
-            performer.getOscillators().add(osc);
-            SimpleSoundbank sbk = new SimpleSoundbank();
-            SimpleInstrument ins = new SimpleInstrument();
-            ins.add(performer);
-            sbk.addInstrument(ins);
-            return sbk;
-        } catch (UnsupportedAudioFileException e1) {
-            return null;
-        } catch (IOException e) {
-            return null;
-        }
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * Soundbank reader that uses audio files as soundbanks.
+ *
+ * @author Karl Helgason
+ */
+public class AudioFileSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(url);
+            Soundbank sbk = getSoundbank(ais);
+            ais.close();
+            return sbk;
+        } catch (UnsupportedAudioFileException e) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        stream.mark(512);
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(stream);
+            Soundbank sbk = getSoundbank(ais);
+            if (sbk != null)
+                return sbk;
+        } catch (UnsupportedAudioFileException e) {
+        } catch (IOException e) {
+        }
+        stream.reset();
+        return null;
+    }
+
+    public Soundbank getSoundbank(AudioInputStream ais)
+            throws InvalidMidiDataException, IOException {
+        try {
+            try {
+                byte[] buffer;
+                if (ais.getFrameLength() == -1) {
+                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    byte[] buff = new byte[1024
+                            - (1024 % ais.getFormat().getFrameSize())];
+                    int ret;
+                    while ((ret = ais.read(buff)) != -1) {
+                        baos.write(buff, 0, ret);
+                    }
+                    ais.close();
+                    buffer = baos.toByteArray();
+                } else {
+                    buffer = new byte[(int)(ais.getFrameLength()
+                                        * ais.getFormat().getFrameSize())];
+                    ais.read(buffer);
+                }
+                ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                        new ModelByteBuffer(buffer), ais.getFormat(), -4800);
+                ModelPerformer performer = new ModelPerformer();
+                performer.getOscillators().add(osc);
+
+                SimpleSoundbank sbk = new SimpleSoundbank();
+                SimpleInstrument ins = new SimpleInstrument();
+                ins.add(performer);
+                sbk.addInstrument(ins);
+                return sbk;
+            } finally {
+            }
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        try {
+            AudioInputStream ais = AudioSystem.getAudioInputStream(file);
+            ais.close();
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                    new ModelByteBuffer(file, 0, file.length()), -4800);
+            ModelPerformer performer = new ModelPerformer();
+            performer.getOscillators().add(osc);
+            SimpleSoundbank sbk = new SimpleSoundbank();
+            SimpleInstrument ins = new SimpleInstrument();
+            ins.add(performer);
+            sbk.addInstrument(ins);
+            return sbk;
+        } catch (UnsupportedAudioFileException e1) {
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatConverter.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,679 +1,679 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioFormat.Encoding;
-
-/**
- * This class is used to convert between 8,16,24,32 bit signed/unsigned
- * big/litle endian fixed/floating point byte buffers and float buffers.
- *
- * @author Karl Helgason
- */
-public abstract class AudioFloatConverter {
-
-    public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
-
-    /***************************************************************************
-     *
-     * 32 bit float, little/big-endian
-     *
-     **************************************************************************/
-
-    // PCM 32 bit float, little-endian
-    private static class AudioFloatConversion32L extends AudioFloatConverter {
-
-        ByteBuffer bytebuffer = null;
-        FloatBuffer floatbuffer = null;
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int in_len = out_len * 4;
-            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
-                bytebuffer = ByteBuffer.allocate(in_len).order(
-                        ByteOrder.LITTLE_ENDIAN);
-                floatbuffer = bytebuffer.asFloatBuffer();
-            }
-            bytebuffer.position(0);
-            floatbuffer.position(0);
-            bytebuffer.put(in_buff, in_offset, in_len);
-            floatbuffer.get(out_buff, out_offset, out_len);
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int out_len = in_len * 4;
-            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
-                bytebuffer = ByteBuffer.allocate(out_len).order(
-                        ByteOrder.LITTLE_ENDIAN);
-                floatbuffer = bytebuffer.asFloatBuffer();
-            }
-            floatbuffer.position(0);
-            bytebuffer.position(0);
-            floatbuffer.put(in_buff, in_offset, in_len);
-            bytebuffer.get(out_buff, out_offset, out_len);
-            return out_buff;
-        }
-    }
-
-    // PCM 32 bit float, big-endian
-    private static class AudioFloatConversion32B extends AudioFloatConverter {
-
-        ByteBuffer bytebuffer = null;
-        FloatBuffer floatbuffer = null;
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int in_len = out_len * 4;
-            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
-                bytebuffer = ByteBuffer.allocate(in_len).order(
-                        ByteOrder.BIG_ENDIAN);
-                floatbuffer = bytebuffer.asFloatBuffer();
-            }
-            bytebuffer.position(0);
-            floatbuffer.position(0);
-            bytebuffer.put(in_buff, in_offset, in_len);
-            floatbuffer.get(out_buff, out_offset, out_len);
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int out_len = in_len * 4;
-            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
-                bytebuffer = ByteBuffer.allocate(out_len).order(
-                        ByteOrder.BIG_ENDIAN);
-                floatbuffer = bytebuffer.asFloatBuffer();
-            }
-            floatbuffer.position(0);
-            bytebuffer.position(0);
-            floatbuffer.put(in_buff, in_offset, in_len);
-            bytebuffer.get(out_buff, out_offset, out_len);
-            return out_buff;
-        }
-    }
-
-    /***************************************************************************
-     *
-     * 8 bit signed/unsigned
-     *
-     **************************************************************************/
-
-    // PCM 8 bit, signed
-    private static class AudioFloatConversion8S extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++)
-                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++)
-                out_buff[ox++] = (byte)(in_buff[ix++] * 127.0f);
-            return out_buff;
-        }
-    }
-
-    // PCM 8 bit, unsigned
-    private static class AudioFloatConversion8U extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++)
-                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127) * (1.0f/127.0f);
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++)
-                out_buff[ox++] = (byte)(127 + in_buff[ix++] * 127.0f);
-            return out_buff;
-        }
-    }
-
-    /***************************************************************************
-     *
-     * 16 bit signed/unsigned, little/big-endian
-     *
-     **************************************************************************/
-
-    // PCM 16 bit, signed, little-endian
-    private static class AudioFloatConversion16SL extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int len = out_offset + out_len;
-            for (int ox = out_offset; ox < len; ox++) {
-                out_buff[ox] = ((short)((in_buff[ix++] & 0xFF) |
-                        (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
-            }
-
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ox = out_offset;
-            int len = in_offset + in_len;
-            for (int ix = in_offset; ix < len; ix++) {
-                int x = (int)(in_buff[ix] * 32767.0);
-                out_buff[ox++] = (byte)x;
-                out_buff[ox++] = (byte)(x >>> 8);
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 16 bit, signed, big-endian
-    private static class AudioFloatConversion16SB extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                out_buff[ox++] = ((short)((in_buff[ix++] << 8) |
-                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * 32767.0);
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)x;
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 16 bit, unsigned, little-endian
-    private static class AudioFloatConversion16UL extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
-                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = 32767 + (int)(in_buff[ix++] * 32767.0);
-                out_buff[ox++] = (byte)x;
-                out_buff[ox++] = (byte)(x >>> 8);
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 16 bit, unsigned, big-endian
-    private static class AudioFloatConversion16UB extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = 32767 + (int)(in_buff[ix++] * 32767.0);
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)x;
-            }
-            return out_buff;
-        }
-    }
-
-    /***************************************************************************
-     *
-     * 24 bit signed/unsigned, little/big-endian
-     *
-     **************************************************************************/
-
-    // PCM 24 bit, signed, little-endian
-    private static class AudioFloatConversion24SL extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
-                        | ((in_buff[ix++] & 0xFF) << 16);
-                if (x > 0x7FFFFF)
-                    x -= 0x1000000;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
-                if (x < 0)
-                    x += 0x1000000;
-                out_buff[ox++] = (byte)x;
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)(x >>> 16);
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 24 bit, signed, big-endian
-    private static class AudioFloatConversion24SB extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = ((in_buff[ix++] & 0xFF) << 16)
-                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                if (x > 0x7FFFFF)
-                    x -= 0x1000000;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
-                if (x < 0)
-                    x += 0x1000000;
-                out_buff[ox++] = (byte)(x >>> 16);
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)x;
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 24 bit, unsigned, little-endian
-    private static class AudioFloatConversion24UL extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
-                        | ((in_buff[ix++] & 0xFF) << 16);
-                x -= 0x7FFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
-                x += 0x7FFFFF;
-                out_buff[ox++] = (byte)x;
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)(x >>> 16);
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 24 bit, unsigned, big-endian
-    private static class AudioFloatConversion24UB extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = ((in_buff[ix++] & 0xFF) << 16)
-                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                x -= 0x7FFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
-                x += 0x7FFFFF;
-                out_buff[ox++] = (byte)(x >>> 16);
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)x;
-            }
-            return out_buff;
-        }
-    }
-
-    /***************************************************************************
-     *
-     * 32 bit signed/unsigned, little/big-endian
-     *
-     **************************************************************************/
-
-    // PCM 32 bit, signed, little-endian
-    private static class AudioFloatConversion32SL extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
-                        ((in_buff[ix++] & 0xFF) << 16) |
-                        ((in_buff[ix++] & 0xFF) << 24);
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
-                out_buff[ox++] = (byte)x;
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)(x >>> 16);
-                out_buff[ox++] = (byte)(x >>> 24);
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 32 bit, signed, big-endian
-    private static class AudioFloatConversion32SB extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = ((in_buff[ix++] & 0xFF) << 24) |
-                        ((in_buff[ix++] & 0xFF) << 16) |
-                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
-                out_buff[ox++] = (byte)(x >>> 24);
-                out_buff[ox++] = (byte)(x >>> 16);
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)x;
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 32 bit, unsigned, little-endian
-    private static class AudioFloatConversion32UL extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
-                        ((in_buff[ix++] & 0xFF) << 16) |
-                        ((in_buff[ix++] & 0xFF) << 24);
-                x -= 0x7FFFFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
-                out_buff[ox++] = (byte)x;
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)(x >>> 16);
-                out_buff[ox++] = (byte)(x >>> 24);
-            }
-            return out_buff;
-        }
-    }
-
-    // PCM 32 bit, unsigned, big-endian
-    private static class AudioFloatConversion32UB extends AudioFloatConverter {
-
-        public float[] toFloatArray(byte[] in_buff, int in_offset,
-                float[] out_buff, int out_offset, int out_len) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < out_len; i++) {
-                int x = ((in_buff[ix++] & 0xFF) << 24) |
-                        ((in_buff[ix++] & 0xFF) << 16) |
-                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
-                x -= 0x7FFFFFFF;
-                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
-            }
-            return out_buff;
-        }
-
-        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-                byte[] out_buff, int out_offset) {
-            int ix = in_offset;
-            int ox = out_offset;
-            for (int i = 0; i < in_len; i++) {
-                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
-                x += 0x7FFFFFFF;
-                out_buff[ox++] = (byte)(x >>> 24);
-                out_buff[ox++] = (byte)(x >>> 16);
-                out_buff[ox++] = (byte)(x >>> 8);
-                out_buff[ox++] = (byte)x;
-            }
-            return out_buff;
-        }
-    }
-
-    public static AudioFloatConverter getConverter(AudioFormat format) {
-        AudioFloatConverter conv = null;
-        if (format.getFrameSize() !=
-                (format.getSampleSizeInBits() / 8) * format.getChannels()) {
-            return null;
-        }
-        if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {
-            if (format.isBigEndian()) {
-                if (format.getSampleSizeInBits() == 8) {
-                    conv = new AudioFloatConversion8S();
-                } else if (format.getSampleSizeInBits() > 8 &&
-                        format.getSampleSizeInBits() <= 16) {
-                    conv = new AudioFloatConversion16SB();
-                } else if (format.getSampleSizeInBits() > 16 &&
-                        format.getSampleSizeInBits() <= 24) {
-                    conv = new AudioFloatConversion24SB();
-                } else if (format.getSampleSizeInBits() > 24 &&
-                        format.getSampleSizeInBits() <= 32) {
-                    conv = new AudioFloatConversion32SB();
-                }
-            } else {
-                if (format.getSampleSizeInBits() == 8) {
-                    conv = new AudioFloatConversion8S();
-                } else if (format.getSampleSizeInBits() > 8 &&
-                        format.getSampleSizeInBits() <= 16) {
-                    conv = new AudioFloatConversion16SL();
-                } else if (format.getSampleSizeInBits() > 16 &&
-                        format.getSampleSizeInBits() <= 24) {
-                    conv = new AudioFloatConversion24SL();
-                } else if (format.getSampleSizeInBits() > 24 &&
-                        format.getSampleSizeInBits() <= 32) {
-                    conv = new AudioFloatConversion32SL();
-                }
-            }
-        } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
-            if (format.isBigEndian()) {
-                if (format.getSampleSizeInBits() == 8) {
-                    conv = new AudioFloatConversion8U();
-                } else if (format.getSampleSizeInBits() > 8 &&
-                        format.getSampleSizeInBits() <= 16) {
-                    conv = new AudioFloatConversion16UB();
-                } else if (format.getSampleSizeInBits() > 16 &&
-                        format.getSampleSizeInBits() <= 24) {
-                    conv = new AudioFloatConversion24UB();
-                } else if (format.getSampleSizeInBits() > 24 &&
-                        format.getSampleSizeInBits() <= 32) {
-                    conv = new AudioFloatConversion32UB();
-                }
-            } else {
-                if (format.getSampleSizeInBits() == 8) {
-                    conv = new AudioFloatConversion8U();
-                } else if (format.getSampleSizeInBits() > 8 &&
-                        format.getSampleSizeInBits() <= 16) {
-                    conv = new AudioFloatConversion16UL();
-                } else if (format.getSampleSizeInBits() > 16 &&
-                        format.getSampleSizeInBits() <= 24) {
-                    conv = new AudioFloatConversion24UL();
-                } else if (format.getSampleSizeInBits() > 24 &&
-                        format.getSampleSizeInBits() <= 32) {
-                    conv = new AudioFloatConversion32UL();
-                }
-            }
-        } else if (format.getEncoding().equals(PCM_FLOAT)) {
-            if (format.getSampleSizeInBits() == 32) {
-                if (format.isBigEndian())
-                    conv = new AudioFloatConversion32B();
-                else
-                    conv = new AudioFloatConversion32L();
-            }
-        }
-
-        if (conv != null)
-            conv.format = format;
-        return conv;
-    }
-    private AudioFormat format;
-
-    public AudioFormat getFormat() {
-        return format;
-    }
-
-    public abstract float[] toFloatArray(byte[] in_buff, int in_offset,
-            float[] out_buff, int out_offset, int out_len);
-
-    public float[] toFloatArray(byte[] in_buff, float[] out_buff,
-            int out_offset, int out_len) {
-        return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);
-    }
-
-    public float[] toFloatArray(byte[] in_buff, int in_offset,
-            float[] out_buff, int out_len) {
-        return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);
-    }
-
-    public float[] toFloatArray(byte[] in_buff, float[] out_buff, int out_len) {
-        return toFloatArray(in_buff, 0, out_buff, 0, out_len);
-    }
-
-    public float[] toFloatArray(byte[] in_buff, float[] out_buff) {
-        return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);
-    }
-
-    public abstract byte[] toByteArray(float[] in_buff, int in_offset,
-            int in_len, byte[] out_buff, int out_offset);
-
-    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff,
-            int out_offset) {
-        return toByteArray(in_buff, 0, in_len, out_buff, out_offset);
-    }
-
-    public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
-            byte[] out_buff) {
-        return toByteArray(in_buff, in_offset, in_len, out_buff, 0);
-    }
-
-    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff) {
-        return toByteArray(in_buff, 0, in_len, out_buff, 0);
-    }
-
-    public byte[] toByteArray(float[] in_buff, byte[] out_buff) {
-        return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * This class is used to convert between 8,16,24,32 bit signed/unsigned
+ * big/litle endian fixed/floating point byte buffers and float buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatConverter {
+
+    public static final Encoding PCM_FLOAT = new Encoding("PCM_FLOAT");
+
+    /***************************************************************************
+     *
+     * 32 bit float, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit float, little-endian
+    private static class AudioFloatConversion32L extends AudioFloatConverter {
+
+        ByteBuffer bytebuffer = null;
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.LITTLE_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit float, big-endian
+    private static class AudioFloatConversion32B extends AudioFloatConverter {
+
+        ByteBuffer bytebuffer = null;
+        FloatBuffer floatbuffer = null;
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int in_len = out_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < in_len) {
+                bytebuffer = ByteBuffer.allocate(in_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            bytebuffer.position(0);
+            floatbuffer.position(0);
+            bytebuffer.put(in_buff, in_offset, in_len);
+            floatbuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int out_len = in_len * 4;
+            if (bytebuffer == null || bytebuffer.capacity() < out_len) {
+                bytebuffer = ByteBuffer.allocate(out_len).order(
+                        ByteOrder.BIG_ENDIAN);
+                floatbuffer = bytebuffer.asFloatBuffer();
+            }
+            floatbuffer.position(0);
+            bytebuffer.position(0);
+            floatbuffer.put(in_buff, in_offset, in_len);
+            bytebuffer.get(out_buff, out_offset, out_len);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 8 bit signed/unsigned
+     *
+     **************************************************************************/
+
+    // PCM 8 bit, signed
+    private static class AudioFloatConversion8S extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = in_buff[ix++] * (1.0f / 127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte)(in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    // PCM 8 bit, unsigned
+    private static class AudioFloatConversion8U extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++)
+                out_buff[ox++] = ((in_buff[ix++] & 0xFF) - 127) * (1.0f/127.0f);
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++)
+                out_buff[ox++] = (byte)(127 + in_buff[ix++] * 127.0f);
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 16 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 16 bit, signed, little-endian
+    private static class AudioFloatConversion16SL extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int len = out_offset + out_len;
+            for (int ox = out_offset; ox < len; ox++) {
+                out_buff[ox] = ((short)((in_buff[ix++] & 0xFF) |
+                        (in_buff[ix++] << 8))) * (1.0f / 32767.0f);
+            }
+
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ox = out_offset;
+            int len = in_offset + in_len;
+            for (int ix = in_offset; ix < len; ix++) {
+                int x = (int)(in_buff[ix] * 32767.0);
+                out_buff[ox++] = (byte)x;
+                out_buff[ox++] = (byte)(x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, signed, big-endian
+    private static class AudioFloatConversion16SB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                out_buff[ox++] = ((short)((in_buff[ix++] << 8) |
+                        (in_buff[ix++] & 0xFF))) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, little-endian
+    private static class AudioFloatConversion16UL extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int)(in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte)x;
+                out_buff[ox++] = (byte)(x >>> 8);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 16 bit, unsigned, big-endian
+    private static class AudioFloatConversion16UB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = (x - 32767) * (1.0f / 32767.0f);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = 32767 + (int)(in_buff[ix++] * 32767.0);
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 24 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 24 bit, signed, little-endian
+    private static class AudioFloatConversion24SL extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte)x;
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)(x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, signed, big-endian
+    private static class AudioFloatConversion24SB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                if (x > 0x7FFFFF)
+                    x -= 0x1000000;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
+                if (x < 0)
+                    x += 0x1000000;
+                out_buff[ox++] = (byte)(x >>> 16);
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, little-endian
+    private static class AudioFloatConversion24UL extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)
+                        | ((in_buff[ix++] & 0xFF) << 16);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte)x;
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)(x >>> 16);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 24 bit, unsigned, big-endian
+    private static class AudioFloatConversion24UB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 16)
+                        | ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFF);
+                x += 0x7FFFFF;
+                out_buff[ox++] = (byte)(x >>> 16);
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)x;
+            }
+            return out_buff;
+        }
+    }
+
+    /***************************************************************************
+     *
+     * 32 bit signed/unsigned, little/big-endian
+     *
+     **************************************************************************/
+
+    // PCM 32 bit, signed, little-endian
+    private static class AudioFloatConversion32SL extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte)x;
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)(x >>> 16);
+                out_buff[ox++] = (byte)(x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, signed, big-endian
+    private static class AudioFloatConversion32SB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
+                out_buff[ox++] = (byte)(x >>> 24);
+                out_buff[ox++] = (byte)(x >>> 16);
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)x;
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, little-endian
+    private static class AudioFloatConversion32UL extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 24);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte)x;
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)(x >>> 16);
+                out_buff[ox++] = (byte)(x >>> 24);
+            }
+            return out_buff;
+        }
+    }
+
+    // PCM 32 bit, unsigned, big-endian
+    private static class AudioFloatConversion32UB extends AudioFloatConverter {
+
+        public float[] toFloatArray(byte[] in_buff, int in_offset,
+                float[] out_buff, int out_offset, int out_len) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < out_len; i++) {
+                int x = ((in_buff[ix++] & 0xFF) << 24) |
+                        ((in_buff[ix++] & 0xFF) << 16) |
+                        ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);
+                x -= 0x7FFFFFFF;
+                out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);
+            }
+            return out_buff;
+        }
+
+        public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+                byte[] out_buff, int out_offset) {
+            int ix = in_offset;
+            int ox = out_offset;
+            for (int i = 0; i < in_len; i++) {
+                int x = (int)(in_buff[ix++] * (float)0x7FFFFFFF);
+                x += 0x7FFFFFFF;
+                out_buff[ox++] = (byte)(x >>> 24);
+                out_buff[ox++] = (byte)(x >>> 16);
+                out_buff[ox++] = (byte)(x >>> 8);
+                out_buff[ox++] = (byte)x;
+            }
+            return out_buff;
+        }
+    }
+
+    public static AudioFloatConverter getConverter(AudioFormat format) {
+        AudioFloatConverter conv = null;
+        if (format.getFrameSize() !=
+                (format.getSampleSizeInBits() / 8) * format.getChannels()) {
+            return null;
+        }
+        if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() == 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SB();
+                }
+            } else {
+                if (format.getSampleSizeInBits() == 8) {
+                    conv = new AudioFloatConversion8S();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16SL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24SL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32SL();
+                }
+            }
+        } else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
+            if (format.isBigEndian()) {
+                if (format.getSampleSizeInBits() == 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UB();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UB();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UB();
+                }
+            } else {
+                if (format.getSampleSizeInBits() == 8) {
+                    conv = new AudioFloatConversion8U();
+                } else if (format.getSampleSizeInBits() > 8 &&
+                        format.getSampleSizeInBits() <= 16) {
+                    conv = new AudioFloatConversion16UL();
+                } else if (format.getSampleSizeInBits() > 16 &&
+                        format.getSampleSizeInBits() <= 24) {
+                    conv = new AudioFloatConversion24UL();
+                } else if (format.getSampleSizeInBits() > 24 &&
+                        format.getSampleSizeInBits() <= 32) {
+                    conv = new AudioFloatConversion32UL();
+                }
+            }
+        } else if (format.getEncoding().equals(PCM_FLOAT)) {
+            if (format.getSampleSizeInBits() == 32) {
+                if (format.isBigEndian())
+                    conv = new AudioFloatConversion32B();
+                else
+                    conv = new AudioFloatConversion32L();
+            }
+        }
+
+        if (conv != null)
+            conv.format = format;
+        return conv;
+    }
+    private AudioFormat format;
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public abstract float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_offset, int out_len);
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff,
+            int out_offset, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, int in_offset,
+            float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff, int out_len) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_len);
+    }
+
+    public float[] toFloatArray(byte[] in_buff, float[] out_buff) {
+        return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);
+    }
+
+    public abstract byte[] toByteArray(float[] in_buff, int in_offset,
+            int in_len, byte[] out_buff, int out_offset);
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff,
+            int out_offset) {
+        return toByteArray(in_buff, 0, in_len, out_buff, out_offset);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,
+            byte[] out_buff) {
+        return toByteArray(in_buff, in_offset, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, int in_len, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_len, out_buff, 0);
+    }
+
+    public byte[] toByteArray(float[] in_buff, byte[] out_buff) {
+        return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioFloatInputStream.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,281 +1,281 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.UnsupportedAudioFileException;
-
-/**
- * This class is used to create AudioFloatInputStream from AudioInputStream and
- * byte buffers.
- *
- * @author Karl Helgason
- */
-public abstract class AudioFloatInputStream {
-
-    private static class BytaArrayAudioFloatInputStream
-            extends AudioFloatInputStream {
-
-        private int pos = 0;
-        private int markpos = 0;
-        private AudioFloatConverter converter;
-        private AudioFormat format;
-        private byte[] buffer;
-        private int buffer_offset;
-        private int buffer_len;
-        private int framesize_pc;
-
-        public BytaArrayAudioFloatInputStream(AudioFloatConverter converter,
-                byte[] buffer, int offset, int len) {
-            this.converter = converter;
-            this.format = converter.getFormat();
-            this.buffer = buffer;
-            this.buffer_offset = offset;
-            framesize_pc = format.getFrameSize() / format.getChannels();
-            this.buffer_len = len / framesize_pc;
-
-        }
-
-        public AudioFormat getFormat() {
-            return format;
-        }
-
-        public long getFrameLength() {
-            return buffer_len;// / format.getFrameSize();
-        }
-
-        public int read(float[] b, int off, int len) throws IOException {
-            if (b == null)
-                throw new NullPointerException();
-            if (off < 0 || len < 0 || len > b.length - off)
-                throw new IndexOutOfBoundsException();
-            if (pos >= buffer_len)
-                return -1;
-            if (len == 0)
-                return 0;
-            if (pos + len > buffer_len)
-                len = buffer_len - pos;
-            converter.toFloatArray(buffer, buffer_offset + pos * framesize_pc,
-                    b, off, len);
-            pos += len;
-            return len;
-        }
-
-        public long skip(long len) throws IOException {
-            if (pos >= buffer_len)
-                return -1;
-            if (len <= 0)
-                return 0;
-            if (pos + len > buffer_len)
-                len = buffer_len - pos;
-            pos += len;
-            return len;
-        }
-
-        public int available() throws IOException {
-            return buffer_len - pos;
-        }
-
-        public void close() throws IOException {
-        }
-
-        public void mark(int readlimit) {
-            markpos = pos;
-        }
-
-        public boolean markSupported() {
-            return true;
-        }
-
-        public void reset() throws IOException {
-            pos = markpos;
-        }
-    }
-
-    private static class DirectAudioFloatInputStream
-            extends AudioFloatInputStream {
-
-        private AudioInputStream stream;
-        private AudioFloatConverter converter;
-        private int framesize_pc; // framesize / channels
-        private byte[] buffer;
-
-        public DirectAudioFloatInputStream(AudioInputStream stream) {
-            converter = AudioFloatConverter.getConverter(stream.getFormat());
-            if (converter == null) {
-                AudioFormat format = stream.getFormat();
-                AudioFormat newformat;
-
-                AudioFormat[] formats = AudioSystem.getTargetFormats(
-                        AudioFormat.Encoding.PCM_SIGNED, format);
-                if (formats.length != 0) {
-                    newformat = formats[0];
-                } else {
-                    float samplerate = format.getSampleRate();
-                    int samplesizeinbits = format.getSampleSizeInBits();
-                    int framesize = format.getFrameSize();
-                    float framerate = format.getFrameRate();
-                    samplesizeinbits = 16;
-                    framesize = format.getChannels() * (samplesizeinbits / 8);
-                    framerate = samplerate;
-
-                    newformat = new AudioFormat(
-                            AudioFormat.Encoding.PCM_SIGNED, samplerate,
-                            samplesizeinbits, format.getChannels(), framesize,
-                            framerate, false);
-                }
-
-                stream = AudioSystem.getAudioInputStream(newformat, stream);
-                converter = AudioFloatConverter.getConverter(stream.getFormat());
-            }
-            framesize_pc = stream.getFormat().getFrameSize()
-                    / stream.getFormat().getChannels();
-            this.stream = stream;
-        }
-
-        public AudioFormat getFormat() {
-            return stream.getFormat();
-        }
-
-        public long getFrameLength() {
-            return stream.getFrameLength();
-        }
-
-        public int read(float[] b, int off, int len) throws IOException {
-            int b_len = len * framesize_pc;
-            if (buffer == null || buffer.length < b_len)
-                buffer = new byte[b_len];
-            int ret = stream.read(buffer, 0, b_len);
-            if (ret == -1)
-                return -1;
-            converter.toFloatArray(buffer, b, off, ret / framesize_pc);
-            return ret / framesize_pc;
-        }
-
-        public long skip(long len) throws IOException {
-            long b_len = len * framesize_pc;
-            long ret = stream.skip(b_len);
-            if (ret == -1)
-                return -1;
-            return ret / framesize_pc;
-        }
-
-        public int available() throws IOException {
-            return stream.available() / framesize_pc;
-        }
-
-        public void close() throws IOException {
-            stream.close();
-        }
-
-        public void mark(int readlimit) {
-            stream.mark(readlimit * framesize_pc);
-        }
-
-        public boolean markSupported() {
-            return stream.markSupported();
-        }
-
-        public void reset() throws IOException {
-            stream.reset();
-        }
-    }
-
-    public static AudioFloatInputStream getInputStream(URL url)
-            throws UnsupportedAudioFileException, IOException {
-        return new DirectAudioFloatInputStream(AudioSystem
-                .getAudioInputStream(url));
-    }
-
-    public static AudioFloatInputStream getInputStream(File file)
-            throws UnsupportedAudioFileException, IOException {
-        return new DirectAudioFloatInputStream(AudioSystem
-                .getAudioInputStream(file));
-    }
-
-    public static AudioFloatInputStream getInputStream(InputStream stream)
-            throws UnsupportedAudioFileException, IOException {
-        return new DirectAudioFloatInputStream(AudioSystem
-                .getAudioInputStream(stream));
-    }
-
-    public static AudioFloatInputStream getInputStream(
-            AudioInputStream stream) {
-        return new DirectAudioFloatInputStream(stream);
-    }
-
-    public static AudioFloatInputStream getInputStream(AudioFormat format,
-            byte[] buffer, int offset, int len) {
-        AudioFloatConverter converter = AudioFloatConverter
-                .getConverter(format);
-        if (converter != null)
-            return new BytaArrayAudioFloatInputStream(converter, buffer,
-                    offset, len);
-
-        InputStream stream = new ByteArrayInputStream(buffer, offset, len);
-        long aLen = format.getFrameSize() == AudioSystem.NOT_SPECIFIED
-                ? AudioSystem.NOT_SPECIFIED : len / format.getFrameSize();
-        AudioInputStream astream = new AudioInputStream(stream, format, aLen);
-        return getInputStream(astream);
-    }
-
-    public abstract AudioFormat getFormat();
-
-    public abstract long getFrameLength();
-
-    public abstract int read(float[] b, int off, int len) throws IOException;
-
-    public int read(float[] b) throws IOException {
-        return read(b, 0, b.length);
-    }
-
-    public float read() throws IOException {
-        float[] b = new float[1];
-        int ret = read(b, 0, 1);
-        if (ret == -1 || ret == 0)
-            return 0;
-        return b[0];
-    }
-
-    public abstract long skip(long len) throws IOException;
-
-    public abstract int available() throws IOException;
-
-    public abstract void close() throws IOException;
-
-    public abstract void mark(int readlimit);
-
-    public abstract boolean markSupported();
-
-    public abstract void reset() throws IOException;
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+
+/**
+ * This class is used to create AudioFloatInputStream from AudioInputStream and
+ * byte buffers.
+ *
+ * @author Karl Helgason
+ */
+public abstract class AudioFloatInputStream {
+
+    private static class BytaArrayAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private int pos = 0;
+        private int markpos = 0;
+        private AudioFloatConverter converter;
+        private AudioFormat format;
+        private byte[] buffer;
+        private int buffer_offset;
+        private int buffer_len;
+        private int framesize_pc;
+
+        public BytaArrayAudioFloatInputStream(AudioFloatConverter converter,
+                byte[] buffer, int offset, int len) {
+            this.converter = converter;
+            this.format = converter.getFormat();
+            this.buffer = buffer;
+            this.buffer_offset = offset;
+            framesize_pc = format.getFrameSize() / format.getChannels();
+            this.buffer_len = len / framesize_pc;
+
+        }
+
+        public AudioFormat getFormat() {
+            return format;
+        }
+
+        public long getFrameLength() {
+            return buffer_len;// / format.getFrameSize();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            if (b == null)
+                throw new NullPointerException();
+            if (off < 0 || len < 0 || len > b.length - off)
+                throw new IndexOutOfBoundsException();
+            if (pos >= buffer_len)
+                return -1;
+            if (len == 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            converter.toFloatArray(buffer, buffer_offset + pos * framesize_pc,
+                    b, off, len);
+            pos += len;
+            return len;
+        }
+
+        public long skip(long len) throws IOException {
+            if (pos >= buffer_len)
+                return -1;
+            if (len <= 0)
+                return 0;
+            if (pos + len > buffer_len)
+                len = buffer_len - pos;
+            pos += len;
+            return len;
+        }
+
+        public int available() throws IOException {
+            return buffer_len - pos;
+        }
+
+        public void close() throws IOException {
+        }
+
+        public void mark(int readlimit) {
+            markpos = pos;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public void reset() throws IOException {
+            pos = markpos;
+        }
+    }
+
+    private static class DirectAudioFloatInputStream
+            extends AudioFloatInputStream {
+
+        private AudioInputStream stream;
+        private AudioFloatConverter converter;
+        private int framesize_pc; // framesize / channels
+        private byte[] buffer;
+
+        public DirectAudioFloatInputStream(AudioInputStream stream) {
+            converter = AudioFloatConverter.getConverter(stream.getFormat());
+            if (converter == null) {
+                AudioFormat format = stream.getFormat();
+                AudioFormat newformat;
+
+                AudioFormat[] formats = AudioSystem.getTargetFormats(
+                        AudioFormat.Encoding.PCM_SIGNED, format);
+                if (formats.length != 0) {
+                    newformat = formats[0];
+                } else {
+                    float samplerate = format.getSampleRate();
+                    int samplesizeinbits = format.getSampleSizeInBits();
+                    int framesize = format.getFrameSize();
+                    float framerate = format.getFrameRate();
+                    samplesizeinbits = 16;
+                    framesize = format.getChannels() * (samplesizeinbits / 8);
+                    framerate = samplerate;
+
+                    newformat = new AudioFormat(
+                            AudioFormat.Encoding.PCM_SIGNED, samplerate,
+                            samplesizeinbits, format.getChannels(), framesize,
+                            framerate, false);
+                }
+
+                stream = AudioSystem.getAudioInputStream(newformat, stream);
+                converter = AudioFloatConverter.getConverter(stream.getFormat());
+            }
+            framesize_pc = stream.getFormat().getFrameSize()
+                    / stream.getFormat().getChannels();
+            this.stream = stream;
+        }
+
+        public AudioFormat getFormat() {
+            return stream.getFormat();
+        }
+
+        public long getFrameLength() {
+            return stream.getFrameLength();
+        }
+
+        public int read(float[] b, int off, int len) throws IOException {
+            int b_len = len * framesize_pc;
+            if (buffer == null || buffer.length < b_len)
+                buffer = new byte[b_len];
+            int ret = stream.read(buffer, 0, b_len);
+            if (ret == -1)
+                return -1;
+            converter.toFloatArray(buffer, b, off, ret / framesize_pc);
+            return ret / framesize_pc;
+        }
+
+        public long skip(long len) throws IOException {
+            long b_len = len * framesize_pc;
+            long ret = stream.skip(b_len);
+            if (ret == -1)
+                return -1;
+            return ret / framesize_pc;
+        }
+
+        public int available() throws IOException {
+            return stream.available() / framesize_pc;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+
+        public void mark(int readlimit) {
+            stream.mark(readlimit * framesize_pc);
+        }
+
+        public boolean markSupported() {
+            return stream.markSupported();
+        }
+
+        public void reset() throws IOException {
+            stream.reset();
+        }
+    }
+
+    public static AudioFloatInputStream getInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(url));
+    }
+
+    public static AudioFloatInputStream getInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(file));
+    }
+
+    public static AudioFloatInputStream getInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+        return new DirectAudioFloatInputStream(AudioSystem
+                .getAudioInputStream(stream));
+    }
+
+    public static AudioFloatInputStream getInputStream(
+            AudioInputStream stream) {
+        return new DirectAudioFloatInputStream(stream);
+    }
+
+    public static AudioFloatInputStream getInputStream(AudioFormat format,
+            byte[] buffer, int offset, int len) {
+        AudioFloatConverter converter = AudioFloatConverter
+                .getConverter(format);
+        if (converter != null)
+            return new BytaArrayAudioFloatInputStream(converter, buffer,
+                    offset, len);
+
+        InputStream stream = new ByteArrayInputStream(buffer, offset, len);
+        long aLen = format.getFrameSize() == AudioSystem.NOT_SPECIFIED
+                ? AudioSystem.NOT_SPECIFIED : len / format.getFrameSize();
+        AudioInputStream astream = new AudioInputStream(stream, format, aLen);
+        return getInputStream(astream);
+    }
+
+    public abstract AudioFormat getFormat();
+
+    public abstract long getFrameLength();
+
+    public abstract int read(float[] b, int off, int len) throws IOException;
+
+    public int read(float[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    public float read() throws IOException {
+        float[] b = new float[1];
+        int ret = read(b, 0, 1);
+        if (ret == -1 || ret == 0)
+            return 0;
+        return b[0];
+    }
+
+    public abstract long skip(long len) throws IOException;
+
+    public abstract int available() throws IOException;
+
+    public abstract void close() throws IOException;
+
+    public abstract void mark(int readlimit);
+
+    public abstract boolean markSupported();
+
+    public abstract void reset() throws IOException;
+}
--- a/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,128 +1,128 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.Map;
-import javax.sound.midi.MidiUnavailableException;
-import javax.sound.midi.Synthesizer;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.SourceDataLine;
-
-/**
- * <code>AudioSynthesizer</code> is a <code>Synthesizer</code>
- * which renders it's output audio into <code>SourceDataLine</code>
- * or <code>AudioInputStream</code>.
- *
- * @see MidiSystem#getSynthesizer
- * @see Synthesizer
- *
- * @author Karl Helgason
- */
-public interface AudioSynthesizer extends Synthesizer {
-
-    /**
-     * Obtains the current format (encoding, sample rate, number of channels,
-     * etc.) of the synthesizer audio data.
-     *
-     * <p>If the synthesizer is not open and has never been opened, it returns
-     * the default format.
-     *
-     * @return current audio data format
-     * @see AudioFormat
-     */
-    public AudioFormat getFormat();
-
-    /**
-     * Gets information about the possible properties for the synthesizer.
-     *
-     * @param info a proposed list of tag/value pairs that will be sent on open.
-     * @return an array of <code>AudioSynthesizerPropertyInfo</code> objects
-     * describing possible properties. This array may be an empty array if
-     * no properties are required.
-     */
-    public AudioSynthesizerPropertyInfo[] getPropertyInfo(
-            Map<String, Object> info);
-
-    /**
-     * Opens the synthesizer and starts rendering audio into
-     * <code>SourceDataLine</code>.
-     *
-     * <p>An application opening a synthesizer explicitly with this call
-     * has to close the synthesizer by calling {@link #close}. This is
-     * necessary to release system resources and allow applications to
-     * exit cleanly.
-     *
-     * <p>Note that some synthesizers, once closed, cannot be reopened.
-     * Attempts to reopen such a synthesizer will always result in
-     * a <code>MidiUnavailableException</code>.
-     *
-     * @param line which <code>AudioSynthesizer</code> writes output audio into.
-     * If <code>line</code> is null, then line from system default mixer is used.
-     * @param info a <code>Map<String,Object></code> object containing
-     * properties for additional configuration supported by synthesizer.
-     * If <code>info</code> is null then default settings are used.
-     *
-     * @throws MidiUnavailableException thrown if the synthesizer cannot be
-     * opened due to resource restrictions.
-     * @throws SecurityException thrown if the synthesizer cannot be
-     * opened due to security restrictions.
-     *
-     * @see #close
-     * @see #isOpen
-     */
-    public void open(SourceDataLine line, Map<String, Object> info)
-            throws MidiUnavailableException;
-
-    /**
-     * Opens the synthesizer and renders audio into returned
-     * <code>AudioInputStream</code>.
-     *
-     * <p>An application opening a synthesizer explicitly with this call
-     * has to close the synthesizer by calling {@link #close}. This is
-     * necessary to release system resources and allow applications to
-     * exit cleanly.
-     *
-     * <p>Note that some synthesizers, once closed, cannot be reopened.
-     * Attempts to reopen such a synthesizer will always result in
-     * a <code>MidiUnavailableException<code>.
-     *
-     * @param targetFormat specifies the <code>AudioFormat</code>
-     * used in returned <code>AudioInputStream</code>.
-     * @param info a <code>Map<String,Object></code> object containing
-     * properties for additional configuration supported by synthesizer.
-     * If <code>info</code> is null then default settings are used.
-     *
-     * @throws MidiUnavailableException thrown if the synthesizer cannot be
-     * opened due to resource restrictions.
-     * @throws SecurityException thrown if the synthesizer cannot be
-     * opened due to security restrictions.
-     *
-     * @see #close
-     * @see #isOpen
-     */
-    public AudioInputStream openStream(AudioFormat targetFormat,
-            Map<String, Object> info) throws MidiUnavailableException;
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Map;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Synthesizer;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * <code>AudioSynthesizer</code> is a <code>Synthesizer</code>
+ * which renders it's output audio into <code>SourceDataLine</code>
+ * or <code>AudioInputStream</code>.
+ *
+ * @see MidiSystem#getSynthesizer
+ * @see Synthesizer
+ *
+ * @author Karl Helgason
+ */
+public interface AudioSynthesizer extends Synthesizer {
+
+    /**
+     * Obtains the current format (encoding, sample rate, number of channels,
+     * etc.) of the synthesizer audio data.
+     *
+     * <p>If the synthesizer is not open and has never been opened, it returns
+     * the default format.
+     *
+     * @return current audio data format
+     * @see AudioFormat
+     */
+    public AudioFormat getFormat();
+
+    /**
+     * Gets information about the possible properties for the synthesizer.
+     *
+     * @param info a proposed list of tag/value pairs that will be sent on open.
+     * @return an array of <code>AudioSynthesizerPropertyInfo</code> objects
+     * describing possible properties. This array may be an empty array if
+     * no properties are required.
+     */
+    public AudioSynthesizerPropertyInfo[] getPropertyInfo(
+            Map<String, Object> info);
+
+    /**
+     * Opens the synthesizer and starts rendering audio into
+     * <code>SourceDataLine</code>.
+     *
+     * <p>An application opening a synthesizer explicitly with this call
+     * has to close the synthesizer by calling {@link #close}. This is
+     * necessary to release system resources and allow applications to
+     * exit cleanly.
+     *
+     * <p>Note that some synthesizers, once closed, cannot be reopened.
+     * Attempts to reopen such a synthesizer will always result in
+     * a <code>MidiUnavailableException</code>.
+     *
+     * @param line which <code>AudioSynthesizer</code> writes output audio into.
+     * If <code>line</code> is null, then line from system default mixer is used.
+     * @param info a <code>Map<String,Object></code> object containing
+     * properties for additional configuration supported by synthesizer.
+     * If <code>info</code> is null then default settings are used.
+     *
+     * @throws MidiUnavailableException thrown if the synthesizer cannot be
+     * opened due to resource restrictions.
+     * @throws SecurityException thrown if the synthesizer cannot be
+     * opened due to security restrictions.
+     *
+     * @see #close
+     * @see #isOpen
+     */
+    public void open(SourceDataLine line, Map<String, Object> info)
+            throws MidiUnavailableException;
+
+    /**
+     * Opens the synthesizer and renders audio into returned
+     * <code>AudioInputStream</code>.
+     *
+     * <p>An application opening a synthesizer explicitly with this call
+     * has to close the synthesizer by calling {@link #close}. This is
+     * necessary to release system resources and allow applications to
+     * exit cleanly.
+     *
+     * <p>Note that some synthesizers, once closed, cannot be reopened.
+     * Attempts to reopen such a synthesizer will always result in
+     * a <code>MidiUnavailableException<code>.
+     *
+     * @param targetFormat specifies the <code>AudioFormat</code>
+     * used in returned <code>AudioInputStream</code>.
+     * @param info a <code>Map<String,Object></code> object containing
+     * properties for additional configuration supported by synthesizer.
+     * If <code>info</code> is null then default settings are used.
+     *
+     * @throws MidiUnavailableException thrown if the synthesizer cannot be
+     * opened due to resource restrictions.
+     * @throws SecurityException thrown if the synthesizer cannot be
+     * opened due to security restrictions.
+     *
+     * @see #close
+     * @see #isOpen
+     */
+    public AudioInputStream openStream(AudioFormat targetFormat,
+            Map<String, Object> info) throws MidiUnavailableException;
+}
--- a/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/AudioSynthesizerPropertyInfo.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,76 +1,76 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Information about property used in  opening <code>AudioSynthesizer</code>.
- *
- * @author Karl Helgason
- */
-public class AudioSynthesizerPropertyInfo {
-
-    /**
-     * Constructs a <code>AudioSynthesizerPropertyInfo</code> object with a given
-     * name and value. The <code>description</code> and <code>choices</code>
-     * are intialized by <code>null</code> values.
-     *
-     * @param name the name of the property
-     * @param value the current value or class used for values.
-     *
-     */
-    public AudioSynthesizerPropertyInfo(String name, Object value) {
-        this.name = name;
-        this.value = value;
-        if (value instanceof Class)
-            valueClass = (Class)value;
-        else if (value != null)
-            valueClass = value.getClass();
-    }
-    /**
-     * The name of the property.
-     */
-    public String name;
-    /**
-     * A brief description of the property, which may be null.
-     */
-    public String description = null;
-    /**
-     * The <code>value</code> field specifies the current value of
-     * the property.
-     */
-    public Object value = null;
-    /**
-     * The <code>valueClass</code> field specifies class
-     * used in <code>value</code> field.
-     */
-    public Class valueClass = null;
-    /**
-     * An array of possible values if the value for the field
-     * <code>AudioSynthesizerPropertyInfo.value</code> may be selected
-     * from a particular set of values; otherwise null.
-     */
-    public Object[] choices = null;
-
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Information about property used in  opening <code>AudioSynthesizer</code>.
+ *
+ * @author Karl Helgason
+ */
+public class AudioSynthesizerPropertyInfo {
+
+    /**
+     * Constructs a <code>AudioSynthesizerPropertyInfo</code> object with a given
+     * name and value. The <code>description</code> and <code>choices</code>
+     * are intialized by <code>null</code> values.
+     *
+     * @param name the name of the property
+     * @param value the current value or class used for values.
+     *
+     */
+    public AudioSynthesizerPropertyInfo(String name, Object value) {
+        this.name = name;
+        this.value = value;
+        if (value instanceof Class)
+            valueClass = (Class)value;
+        else if (value != null)
+            valueClass = value.getClass();
+    }
+    /**
+     * The name of the property.
+     */
+    public String name;
+    /**
+     * A brief description of the property, which may be null.
+     */
+    public String description = null;
+    /**
+     * The <code>value</code> field specifies the current value of
+     * the property.
+     */
+    public Object value = null;
+    /**
+     * The <code>valueClass</code> field specifies class
+     * used in <code>value</code> field.
+     */
+    public Class valueClass = null;
+    /**
+     * An array of possible values if the value for the field
+     * <code>AudioSynthesizerPropertyInfo.value</code> may be selected
+     * from a particular set of values; otherwise null.
+     */
+    public Object[] choices = null;
+
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSInfo.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSInfo.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,109 +1,109 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This class is used to store information  to describe soundbanks, instruments
- * and samples. It is stored inside a "INFO" List Chunk inside DLS files.
- *
- * @author Karl Helgason
- */
-public class DLSInfo {
-
-    /**
-     * (INAM) Title or subject.
-     */
-    public String name = "untitled";
-    /**
-     * (ICRD) Date of creation, the format is: YYYY-MM-DD.
-     *        For example 2007-01-01 for 1. january of year 2007.
-     */
-    public String creationDate = null;
-    /**
-     * (IENG) Name of engineer who created the object.
-     */
-    public String engineers = null;
-    /**
-     * (IPRD) Name of the product which the object is intended for.
-     */
-    public String product = null;
-    /**
-     * (ICOP) Copyright information.
-     */
-    public String copyright = null;
-    /**
-     * (ICMT) General comments. Doesn't contain newline characters.
-     */
-    public String comments = null;
-    /**
-     * (ISFT) Name of software package used to create the file.
-     */
-    public String tools = null;
-    /**
-     * (IARL) Where content is archived.
-     */
-    public String archival_location = null;
-    /**
-     * (IART) Artists of original content.
-     */
-    public String artist = null;
-    /**
-     * (ICMS) Names of persons or orginizations who commissioned the file.
-     */
-    public String commissioned = null;
-    /**
-     * (IGNR) Genre of the work.
-     *        Example: jazz, classical, rock, etc.
-     */
-    public String genre = null;
-    /**
-     * (IKEY) List of keyword that describe the content.
-     *        Examples: FX, bird, piano, etc.
-     */
-    public String keywords = null;
-    /**
-     * (IMED) Describes original medium of the data.
-     *        For example: record, CD, etc.
-     */
-    public String medium = null;
-    /**
-     * (ISBJ) Description of the content.
-     */
-    public String subject = null;
-    /**
-     * (ISRC) Name of person or orginization who supplied
-     *        orginal material for the file.
-     */
-    public String source = null;
-    /**
-     * (ISRF) Source media for sample data is from.
-     *        For example: CD, TV, etc.
-     */
-    public String source_form = null;
-    /**
-     * (ITCH) Technician who sample the file/object.
-     */
-    public String technician = null;
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store information  to describe soundbanks, instruments
+ * and samples. It is stored inside a "INFO" List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSInfo {
+
+    /**
+     * (INAM) Title or subject.
+     */
+    public String name = "untitled";
+    /**
+     * (ICRD) Date of creation, the format is: YYYY-MM-DD.
+     *        For example 2007-01-01 for 1. january of year 2007.
+     */
+    public String creationDate = null;
+    /**
+     * (IENG) Name of engineer who created the object.
+     */
+    public String engineers = null;
+    /**
+     * (IPRD) Name of the product which the object is intended for.
+     */
+    public String product = null;
+    /**
+     * (ICOP) Copyright information.
+     */
+    public String copyright = null;
+    /**
+     * (ICMT) General comments. Doesn't contain newline characters.
+     */
+    public String comments = null;
+    /**
+     * (ISFT) Name of software package used to create the file.
+     */
+    public String tools = null;
+    /**
+     * (IARL) Where content is archived.
+     */
+    public String archival_location = null;
+    /**
+     * (IART) Artists of original content.
+     */
+    public String artist = null;
+    /**
+     * (ICMS) Names of persons or orginizations who commissioned the file.
+     */
+    public String commissioned = null;
+    /**
+     * (IGNR) Genre of the work.
+     *        Example: jazz, classical, rock, etc.
+     */
+    public String genre = null;
+    /**
+     * (IKEY) List of keyword that describe the content.
+     *        Examples: FX, bird, piano, etc.
+     */
+    public String keywords = null;
+    /**
+     * (IMED) Describes original medium of the data.
+     *        For example: record, CD, etc.
+     */
+    public String medium = null;
+    /**
+     * (ISBJ) Description of the content.
+     */
+    public String subject = null;
+    /**
+     * (ISRC) Name of person or orginization who supplied
+     *        orginal material for the file.
+     */
+    public String source = null;
+    /**
+     * (ISRF) Source media for sample data is from.
+     *        For example: CD, TV, etc.
+     */
+    public String source_form = null;
+    /**
+     * (ITCH) Technician who sample the file/object.
+     */
+    public String technician = null;
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSInstrument.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,448 +1,448 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.sound.midi.Patch;
-
-/**
- * This class is used to store information to describe instrument.
- * It contains list of regions and modulators.
- * It is stored inside a "ins " List Chunk inside DLS files.
- * In the DLS documentation a modulator is called articulator.
- *
- * @author Karl Helgason
- */
-public class DLSInstrument extends ModelInstrument {
-
-    protected int preset = 0;
-    protected int bank = 0;
-    protected boolean druminstrument = false;
-    protected byte[] guid = null;
-    protected DLSInfo info = new DLSInfo();
-    protected List<DLSRegion> regions = new ArrayList<DLSRegion>();
-    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
-
-    public DLSInstrument() {
-        super(null, null, null, null);
-    }
-
-    public DLSInstrument(DLSSoundbank soundbank) {
-        super(soundbank, null, null, null);
-    }
-
-    public DLSInfo getInfo() {
-        return info;
-    }
-
-    public String getName() {
-        return info.name;
-    }
-
-    public void setName(String name) {
-        info.name = name;
-    }
-
-    public ModelPatch getPatch() {
-        return new ModelPatch(bank, preset, druminstrument);
-    }
-
-    public void setPatch(Patch patch) {
-        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
-            druminstrument = true;
-            bank = patch.getBank();
-            preset = patch.getProgram();
-        } else {
-            druminstrument = false;
-            bank = patch.getBank();
-            preset = patch.getProgram();
-        }
-    }
-
-    public Object getData() {
-        return null;
-    }
-
-    public List<DLSRegion> getRegions() {
-        return regions;
-    }
-
-    public List<DLSModulator> getModulators() {
-        return modulators;
-    }
-
-    public String toString() {
-        if (druminstrument)
-            return "Drumkit: " + info.name
-                    + " bank #" + bank + " preset #" + preset;
-        else
-            return "Instrument: " + info.name
-                    + " bank #" + bank + " preset #" + preset;
-    }
-
-    private ModelIdentifier convertToModelDest(int dest) {
-        if (dest == DLSModulator.CONN_DST_NONE)
-            return null;
-        if (dest == DLSModulator.CONN_DST_GAIN)
-            return ModelDestination.DESTINATION_GAIN;
-        if (dest == DLSModulator.CONN_DST_PITCH)
-            return ModelDestination.DESTINATION_PITCH;
-        if (dest == DLSModulator.CONN_DST_PAN)
-            return ModelDestination.DESTINATION_PAN;
-
-        if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)
-            return ModelDestination.DESTINATION_LFO1_FREQ;
-        if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)
-            return ModelDestination.DESTINATION_LFO1_DELAY;
-
-        if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)
-            return ModelDestination.DESTINATION_EG1_ATTACK;
-        if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)
-            return ModelDestination.DESTINATION_EG1_DECAY;
-        if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)
-            return ModelDestination.DESTINATION_EG1_RELEASE;
-        if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)
-            return ModelDestination.DESTINATION_EG1_SUSTAIN;
-
-        if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)
-            return ModelDestination.DESTINATION_EG2_ATTACK;
-        if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)
-            return ModelDestination.DESTINATION_EG2_DECAY;
-        if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)
-            return ModelDestination.DESTINATION_EG2_RELEASE;
-        if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)
-            return ModelDestination.DESTINATION_EG2_SUSTAIN;
-
-        // DLS2 Destinations
-        if (dest == DLSModulator.CONN_DST_KEYNUMBER)
-            return ModelDestination.DESTINATION_KEYNUMBER;
-
-        if (dest == DLSModulator.CONN_DST_CHORUS)
-            return ModelDestination.DESTINATION_CHORUS;
-        if (dest == DLSModulator.CONN_DST_REVERB)
-            return ModelDestination.DESTINATION_REVERB;
-
-        if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)
-            return ModelDestination.DESTINATION_LFO2_FREQ;
-        if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)
-            return ModelDestination.DESTINATION_LFO2_DELAY;
-
-        if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)
-            return ModelDestination.DESTINATION_EG1_DELAY;
-        if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)
-            return ModelDestination.DESTINATION_EG1_HOLD;
-        if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)
-            return ModelDestination.DESTINATION_EG1_SHUTDOWN;
-
-        if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)
-            return ModelDestination.DESTINATION_EG2_DELAY;
-        if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)
-            return ModelDestination.DESTINATION_EG2_HOLD;
-
-        if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)
-            return ModelDestination.DESTINATION_FILTER_FREQ;
-        if (dest == DLSModulator.CONN_DST_FILTER_Q)
-            return ModelDestination.DESTINATION_FILTER_Q;
-
-        return null;
-    }
-
-    private ModelIdentifier convertToModelSrc(int src) {
-        if (src == DLSModulator.CONN_SRC_NONE)
-            return null;
-
-        if (src == DLSModulator.CONN_SRC_LFO)
-            return ModelSource.SOURCE_LFO1;
-        if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)
-            return ModelSource.SOURCE_NOTEON_VELOCITY;
-        if (src == DLSModulator.CONN_SRC_KEYNUMBER)
-            return ModelSource.SOURCE_NOTEON_KEYNUMBER;
-        if (src == DLSModulator.CONN_SRC_EG1)
-            return ModelSource.SOURCE_EG1;
-        if (src == DLSModulator.CONN_SRC_EG2)
-            return ModelSource.SOURCE_EG2;
-        if (src == DLSModulator.CONN_SRC_PITCHWHEEL)
-            return ModelSource.SOURCE_MIDI_PITCH;
-        if (src == DLSModulator.CONN_SRC_CC1)
-            return new ModelIdentifier("midi_cc", "1", 0);
-        if (src == DLSModulator.CONN_SRC_CC7)
-            return new ModelIdentifier("midi_cc", "7", 0);
-        if (src == DLSModulator.CONN_SRC_CC10)
-            return new ModelIdentifier("midi_cc", "10", 0);
-        if (src == DLSModulator.CONN_SRC_CC11)
-            return new ModelIdentifier("midi_cc", "11", 0);
-        if (src == DLSModulator.CONN_SRC_RPN0)
-            return new ModelIdentifier("midi_rpn", "0", 0);
-        if (src == DLSModulator.CONN_SRC_RPN1)
-            return new ModelIdentifier("midi_rpn", "1", 0);
-
-        if (src == DLSModulator.CONN_SRC_POLYPRESSURE)
-            return ModelSource.SOURCE_MIDI_POLY_PRESSURE;
-        if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)
-            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
-        if (src == DLSModulator.CONN_SRC_VIBRATO)
-            return ModelSource.SOURCE_LFO2;
-        if (src == DLSModulator.CONN_SRC_MONOPRESSURE)
-            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
-
-        if (src == DLSModulator.CONN_SRC_CC91)
-            return new ModelIdentifier("midi_cc", "91", 0);
-        if (src == DLSModulator.CONN_SRC_CC93)
-            return new ModelIdentifier("midi_cc", "93", 0);
-
-        return null;
-    }
-
-    private ModelConnectionBlock convertToModel(DLSModulator mod) {
-        ModelIdentifier source = convertToModelSrc(mod.getSource());
-        ModelIdentifier control = convertToModelSrc(mod.getControl());
-        ModelIdentifier destination_id =
-                convertToModelDest(mod.getDestination());
-
-        int scale = mod.getScale();
-        double f_scale;
-        if (scale == Integer.MIN_VALUE)
-            f_scale = Double.NEGATIVE_INFINITY;
-        else
-            f_scale = scale / 65536.0;
-
-        if (destination_id != null) {
-            ModelSource src = null;
-            ModelSource ctrl = null;
-            ModelConnectionBlock block = new ModelConnectionBlock();
-            if (control != null) {
-                ModelSource s = new ModelSource();
-                if (control == ModelSource.SOURCE_MIDI_PITCH) {
-                    ((ModelStandardTransform)s.getTransform()).setPolarity(
-                            ModelStandardTransform.POLARITY_BIPOLAR);
-                } else if (control == ModelSource.SOURCE_LFO1
-                        || control == ModelSource.SOURCE_LFO2) {
-                    ((ModelStandardTransform)s.getTransform()).setPolarity(
-                            ModelStandardTransform.POLARITY_BIPOLAR);
-                }
-                s.setIdentifier(control);
-                block.addSource(s);
-                ctrl = s;
-            }
-            if (source != null) {
-                ModelSource s = new ModelSource();
-                if (source == ModelSource.SOURCE_MIDI_PITCH) {
-                    ((ModelStandardTransform)s.getTransform()).setPolarity(
-                            ModelStandardTransform.POLARITY_BIPOLAR);
-                } else if (source == ModelSource.SOURCE_LFO1
-                        || source == ModelSource.SOURCE_LFO2) {
-                    ((ModelStandardTransform)s.getTransform()).setPolarity(
-                            ModelStandardTransform.POLARITY_BIPOLAR);
-                }
-                s.setIdentifier(source);
-                block.addSource(s);
-                src = s;
-            }
-            ModelDestination destination = new ModelDestination();
-            destination.setIdentifier(destination_id);
-            block.setDestination(destination);
-
-            if (mod.getVersion() == 1) {
-                //if (mod.getTransform() ==  DLSModulator.CONN_TRN_CONCAVE) {
-                //    ((ModelStandardTransform)destination.getTransform())
-                //            .setTransform(
-                //            ModelStandardTransform.TRANSFORM_CONCAVE);
-                //}
-                if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
-                    if (src != null) {
-                        ((ModelStandardTransform)src.getTransform())
-                                .setTransform(
-                                    ModelStandardTransform.TRANSFORM_CONCAVE);
-                        ((ModelStandardTransform)src.getTransform())
-                                .setDirection(
-                                    ModelStandardTransform.DIRECTION_MAX2MIN);
-                    }
-                    if (ctrl != null) {
-                        ((ModelStandardTransform)ctrl.getTransform())
-                                .setTransform(
-                                    ModelStandardTransform.TRANSFORM_CONCAVE);
-                        ((ModelStandardTransform)ctrl.getTransform())
-                                .setDirection(
-                                    ModelStandardTransform.DIRECTION_MAX2MIN);
-                    }
-                }
-
-            } else if (mod.getVersion() == 2) {
-                int transform = mod.getTransform();
-                int src_transform_invert = (transform >> 15) & 1;
-                int src_transform_bipolar = (transform >> 14) & 1;
-                int src_transform = (transform >> 10) & 8;
-                int ctr_transform_invert = (transform >> 9) & 1;
-                int ctr_transform_bipolar = (transform >> 8) & 1;
-                int ctr_transform = (transform >> 4) & 8;
-
-
-                if (src != null) {
-                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
-                    if (src_transform == DLSModulator.CONN_TRN_SWITCH)
-                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
-                    if (src_transform == DLSModulator.CONN_TRN_CONCAVE)
-                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
-                    if (src_transform == DLSModulator.CONN_TRN_CONVEX)
-                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
-                    ((ModelStandardTransform)src.getTransform())
-                            .setTransform(trans);
-                    ((ModelStandardTransform)src.getTransform())
-                            .setPolarity(src_transform_bipolar == 1);
-                    ((ModelStandardTransform)src.getTransform())
-                            .setDirection(src_transform_invert == 1);
-
-                }
-
-                if (ctrl != null) {
-                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
-                    if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)
-                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
-                    if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)
-                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
-                    if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)
-                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
-                    ((ModelStandardTransform)ctrl.getTransform())
-                            .setTransform(trans);
-                    ((ModelStandardTransform)ctrl.getTransform())
-                            .setPolarity(ctr_transform_bipolar == 1);
-                    ((ModelStandardTransform)ctrl.getTransform())
-                            .setDirection(ctr_transform_invert == 1);
-                }
-
-                /* No output transforms are defined the DLS Level 2
-                int out_transform = transform % 8;
-                int trans = ModelStandardTransform.TRANSFORM_LINEAR;
-                if (out_transform == DLSModulator.CONN_TRN_SWITCH)
-                    trans = ModelStandardTransform.TRANSFORM_SWITCH;
-                if (out_transform == DLSModulator.CONN_TRN_CONCAVE)
-                    trans = ModelStandardTransform.TRANSFORM_CONCAVE;
-                if (out_transform == DLSModulator.CONN_TRN_CONVEX)
-                    trans = ModelStandardTransform.TRANSFORM_CONVEX;
-                if (ctrl != null) {
-                    ((ModelStandardTransform)destination.getTransform())
-                            .setTransform(trans);
-                }
-                */
-
-            }
-
-            block.setScale(f_scale);
-
-            return block;
-        }
-
-        return null;
-    }
-
-    public ModelPerformer[] getPerformers() {
-        List<ModelPerformer> performers = new ArrayList<ModelPerformer>();
-
-        Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>();
-        for (DLSModulator mod: getModulators()) {
-            modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
-                    mod.getDestination(), mod);
-        }
-
-        Map<String, DLSModulator> insmodmap =
-                new HashMap<String, DLSModulator>();
-
-        for (DLSRegion zone: regions) {
-            ModelPerformer performer = new ModelPerformer();
-            performer.setName(zone.getSample().getName());
-            performer.setSelfNonExclusive((zone.getFusoptions() &
-                    DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);
-            performer.setExclusiveClass(zone.getExclusiveClass());
-            performer.setKeyFrom(zone.getKeyfrom());
-            performer.setKeyTo(zone.getKeyto());
-            performer.setVelFrom(zone.getVelfrom());
-            performer.setVelTo(zone.getVelto());
-
-            insmodmap.clear();
-            insmodmap.putAll(modmap);
-            for (DLSModulator mod: zone.getModulators()) {
-                insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
-                        mod.getDestination(), mod);
-            }
-
-            List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();
-            for (DLSModulator mod: insmodmap.values()) {
-                ModelConnectionBlock p = convertToModel(mod);
-                if (p != null)
-                    blocks.add(p);
-            }
-
-
-            DLSSample sample = zone.getSample();
-            DLSSampleOptions sampleopt = zone.getSampleoptions();
-            if (sampleopt == null)
-                sampleopt = sample.getSampleoptions();
-
-            ModelByteBuffer buff = sample.getDataBuffer();
-
-            float pitchcorrection = (-sampleopt.unitynote * 100) +
-                    sampleopt.finetune;
-
-            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,
-                    sample.getFormat(), pitchcorrection);
-            osc.setAttenuation(osc.getAttenuation() / 65536f);
-            if (sampleopt.getLoops().size() != 0) {
-                DLSSampleLoop loop = sampleopt.getLoops().get(0);
-                osc.setLoopStart((int)loop.getStart());
-                osc.setLoopLength((int)loop.getLength());
-                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)
-                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
-                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)
-                    osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
-                else
-                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
-            }
-
-            performer.getConnectionBlocks().add(
-                    new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,
-                        new ModelDestination(
-                            new ModelIdentifier("filter", "type", 1))));
-
-            performer.getOscillators().add(osc);
-
-            performers.add(performer);
-
-        }
-
-        return performers.toArray(new ModelPerformer[performers.size()]);
-    }
-
-    public byte[] getGuid() {
-        return guid;
-    }
-
-    public void setGuid(byte[] guid) {
-        this.guid = guid;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Patch;
+
+/**
+ * This class is used to store information to describe instrument.
+ * It contains list of regions and modulators.
+ * It is stored inside a "ins " List Chunk inside DLS files.
+ * In the DLS documentation a modulator is called articulator.
+ *
+ * @author Karl Helgason
+ */
+public class DLSInstrument extends ModelInstrument {
+
+    protected int preset = 0;
+    protected int bank = 0;
+    protected boolean druminstrument = false;
+    protected byte[] guid = null;
+    protected DLSInfo info = new DLSInfo();
+    protected List<DLSRegion> regions = new ArrayList<DLSRegion>();
+    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
+
+    public DLSInstrument() {
+        super(null, null, null, null);
+    }
+
+    public DLSInstrument(DLSSoundbank soundbank) {
+        super(soundbank, null, null, null);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public void setName(String name) {
+        info.name = name;
+    }
+
+    public ModelPatch getPatch() {
+        return new ModelPatch(bank, preset, druminstrument);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
+            druminstrument = true;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        } else {
+            druminstrument = false;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        }
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public List<DLSRegion> getRegions() {
+        return regions;
+    }
+
+    public List<DLSModulator> getModulators() {
+        return modulators;
+    }
+
+    public String toString() {
+        if (druminstrument)
+            return "Drumkit: " + info.name
+                    + " bank #" + bank + " preset #" + preset;
+        else
+            return "Instrument: " + info.name
+                    + " bank #" + bank + " preset #" + preset;
+    }
+
+    private ModelIdentifier convertToModelDest(int dest) {
+        if (dest == DLSModulator.CONN_DST_NONE)
+            return null;
+        if (dest == DLSModulator.CONN_DST_GAIN)
+            return ModelDestination.DESTINATION_GAIN;
+        if (dest == DLSModulator.CONN_DST_PITCH)
+            return ModelDestination.DESTINATION_PITCH;
+        if (dest == DLSModulator.CONN_DST_PAN)
+            return ModelDestination.DESTINATION_PAN;
+
+        if (dest == DLSModulator.CONN_DST_LFO_FREQUENCY)
+            return ModelDestination.DESTINATION_LFO1_FREQ;
+        if (dest == DLSModulator.CONN_DST_LFO_STARTDELAY)
+            return ModelDestination.DESTINATION_LFO1_DELAY;
+
+        if (dest == DLSModulator.CONN_DST_EG1_ATTACKTIME)
+            return ModelDestination.DESTINATION_EG1_ATTACK;
+        if (dest == DLSModulator.CONN_DST_EG1_DECAYTIME)
+            return ModelDestination.DESTINATION_EG1_DECAY;
+        if (dest == DLSModulator.CONN_DST_EG1_RELEASETIME)
+            return ModelDestination.DESTINATION_EG1_RELEASE;
+        if (dest == DLSModulator.CONN_DST_EG1_SUSTAINLEVEL)
+            return ModelDestination.DESTINATION_EG1_SUSTAIN;
+
+        if (dest == DLSModulator.CONN_DST_EG2_ATTACKTIME)
+            return ModelDestination.DESTINATION_EG2_ATTACK;
+        if (dest == DLSModulator.CONN_DST_EG2_DECAYTIME)
+            return ModelDestination.DESTINATION_EG2_DECAY;
+        if (dest == DLSModulator.CONN_DST_EG2_RELEASETIME)
+            return ModelDestination.DESTINATION_EG2_RELEASE;
+        if (dest == DLSModulator.CONN_DST_EG2_SUSTAINLEVEL)
+            return ModelDestination.DESTINATION_EG2_SUSTAIN;
+
+        // DLS2 Destinations
+        if (dest == DLSModulator.CONN_DST_KEYNUMBER)
+            return ModelDestination.DESTINATION_KEYNUMBER;
+
+        if (dest == DLSModulator.CONN_DST_CHORUS)
+            return ModelDestination.DESTINATION_CHORUS;
+        if (dest == DLSModulator.CONN_DST_REVERB)
+            return ModelDestination.DESTINATION_REVERB;
+
+        if (dest == DLSModulator.CONN_DST_VIB_FREQUENCY)
+            return ModelDestination.DESTINATION_LFO2_FREQ;
+        if (dest == DLSModulator.CONN_DST_VIB_STARTDELAY)
+            return ModelDestination.DESTINATION_LFO2_DELAY;
+
+        if (dest == DLSModulator.CONN_DST_EG1_DELAYTIME)
+            return ModelDestination.DESTINATION_EG1_DELAY;
+        if (dest == DLSModulator.CONN_DST_EG1_HOLDTIME)
+            return ModelDestination.DESTINATION_EG1_HOLD;
+        if (dest == DLSModulator.CONN_DST_EG1_SHUTDOWNTIME)
+            return ModelDestination.DESTINATION_EG1_SHUTDOWN;
+
+        if (dest == DLSModulator.CONN_DST_EG2_DELAYTIME)
+            return ModelDestination.DESTINATION_EG2_DELAY;
+        if (dest == DLSModulator.CONN_DST_EG2_HOLDTIME)
+            return ModelDestination.DESTINATION_EG2_HOLD;
+
+        if (dest == DLSModulator.CONN_DST_FILTER_CUTOFF)
+            return ModelDestination.DESTINATION_FILTER_FREQ;
+        if (dest == DLSModulator.CONN_DST_FILTER_Q)
+            return ModelDestination.DESTINATION_FILTER_Q;
+
+        return null;
+    }
+
+    private ModelIdentifier convertToModelSrc(int src) {
+        if (src == DLSModulator.CONN_SRC_NONE)
+            return null;
+
+        if (src == DLSModulator.CONN_SRC_LFO)
+            return ModelSource.SOURCE_LFO1;
+        if (src == DLSModulator.CONN_SRC_KEYONVELOCITY)
+            return ModelSource.SOURCE_NOTEON_VELOCITY;
+        if (src == DLSModulator.CONN_SRC_KEYNUMBER)
+            return ModelSource.SOURCE_NOTEON_KEYNUMBER;
+        if (src == DLSModulator.CONN_SRC_EG1)
+            return ModelSource.SOURCE_EG1;
+        if (src == DLSModulator.CONN_SRC_EG2)
+            return ModelSource.SOURCE_EG2;
+        if (src == DLSModulator.CONN_SRC_PITCHWHEEL)
+            return ModelSource.SOURCE_MIDI_PITCH;
+        if (src == DLSModulator.CONN_SRC_CC1)
+            return new ModelIdentifier("midi_cc", "1", 0);
+        if (src == DLSModulator.CONN_SRC_CC7)
+            return new ModelIdentifier("midi_cc", "7", 0);
+        if (src == DLSModulator.CONN_SRC_CC10)
+            return new ModelIdentifier("midi_cc", "10", 0);
+        if (src == DLSModulator.CONN_SRC_CC11)
+            return new ModelIdentifier("midi_cc", "11", 0);
+        if (src == DLSModulator.CONN_SRC_RPN0)
+            return new ModelIdentifier("midi_rpn", "0", 0);
+        if (src == DLSModulator.CONN_SRC_RPN1)
+            return new ModelIdentifier("midi_rpn", "1", 0);
+
+        if (src == DLSModulator.CONN_SRC_POLYPRESSURE)
+            return ModelSource.SOURCE_MIDI_POLY_PRESSURE;
+        if (src == DLSModulator.CONN_SRC_CHANNELPRESSURE)
+            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+        if (src == DLSModulator.CONN_SRC_VIBRATO)
+            return ModelSource.SOURCE_LFO2;
+        if (src == DLSModulator.CONN_SRC_MONOPRESSURE)
+            return ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+
+        if (src == DLSModulator.CONN_SRC_CC91)
+            return new ModelIdentifier("midi_cc", "91", 0);
+        if (src == DLSModulator.CONN_SRC_CC93)
+            return new ModelIdentifier("midi_cc", "93", 0);
+
+        return null;
+    }
+
+    private ModelConnectionBlock convertToModel(DLSModulator mod) {
+        ModelIdentifier source = convertToModelSrc(mod.getSource());
+        ModelIdentifier control = convertToModelSrc(mod.getControl());
+        ModelIdentifier destination_id =
+                convertToModelDest(mod.getDestination());
+
+        int scale = mod.getScale();
+        double f_scale;
+        if (scale == Integer.MIN_VALUE)
+            f_scale = Double.NEGATIVE_INFINITY;
+        else
+            f_scale = scale / 65536.0;
+
+        if (destination_id != null) {
+            ModelSource src = null;
+            ModelSource ctrl = null;
+            ModelConnectionBlock block = new ModelConnectionBlock();
+            if (control != null) {
+                ModelSource s = new ModelSource();
+                if (control == ModelSource.SOURCE_MIDI_PITCH) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                } else if (control == ModelSource.SOURCE_LFO1
+                        || control == ModelSource.SOURCE_LFO2) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                }
+                s.setIdentifier(control);
+                block.addSource(s);
+                ctrl = s;
+            }
+            if (source != null) {
+                ModelSource s = new ModelSource();
+                if (source == ModelSource.SOURCE_MIDI_PITCH) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                } else if (source == ModelSource.SOURCE_LFO1
+                        || source == ModelSource.SOURCE_LFO2) {
+                    ((ModelStandardTransform)s.getTransform()).setPolarity(
+                            ModelStandardTransform.POLARITY_BIPOLAR);
+                }
+                s.setIdentifier(source);
+                block.addSource(s);
+                src = s;
+            }
+            ModelDestination destination = new ModelDestination();
+            destination.setIdentifier(destination_id);
+            block.setDestination(destination);
+
+            if (mod.getVersion() == 1) {
+                //if (mod.getTransform() ==  DLSModulator.CONN_TRN_CONCAVE) {
+                //    ((ModelStandardTransform)destination.getTransform())
+                //            .setTransform(
+                //            ModelStandardTransform.TRANSFORM_CONCAVE);
+                //}
+                if (mod.getTransform() == DLSModulator.CONN_TRN_CONCAVE) {
+                    if (src != null) {
+                        ((ModelStandardTransform)src.getTransform())
+                                .setTransform(
+                                    ModelStandardTransform.TRANSFORM_CONCAVE);
+                        ((ModelStandardTransform)src.getTransform())
+                                .setDirection(
+                                    ModelStandardTransform.DIRECTION_MAX2MIN);
+                    }
+                    if (ctrl != null) {
+                        ((ModelStandardTransform)ctrl.getTransform())
+                                .setTransform(
+                                    ModelStandardTransform.TRANSFORM_CONCAVE);
+                        ((ModelStandardTransform)ctrl.getTransform())
+                                .setDirection(
+                                    ModelStandardTransform.DIRECTION_MAX2MIN);
+                    }
+                }
+
+            } else if (mod.getVersion() == 2) {
+                int transform = mod.getTransform();
+                int src_transform_invert = (transform >> 15) & 1;
+                int src_transform_bipolar = (transform >> 14) & 1;
+                int src_transform = (transform >> 10) & 8;
+                int ctr_transform_invert = (transform >> 9) & 1;
+                int ctr_transform_bipolar = (transform >> 8) & 1;
+                int ctr_transform = (transform >> 4) & 8;
+
+
+                if (src != null) {
+                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                    if (src_transform == DLSModulator.CONN_TRN_SWITCH)
+                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                    if (src_transform == DLSModulator.CONN_TRN_CONCAVE)
+                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                    if (src_transform == DLSModulator.CONN_TRN_CONVEX)
+                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                    ((ModelStandardTransform)src.getTransform())
+                            .setTransform(trans);
+                    ((ModelStandardTransform)src.getTransform())
+                            .setPolarity(src_transform_bipolar == 1);
+                    ((ModelStandardTransform)src.getTransform())
+                            .setDirection(src_transform_invert == 1);
+
+                }
+
+                if (ctrl != null) {
+                    int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                    if (ctr_transform == DLSModulator.CONN_TRN_SWITCH)
+                        trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                    if (ctr_transform == DLSModulator.CONN_TRN_CONCAVE)
+                        trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                    if (ctr_transform == DLSModulator.CONN_TRN_CONVEX)
+                        trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setTransform(trans);
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setPolarity(ctr_transform_bipolar == 1);
+                    ((ModelStandardTransform)ctrl.getTransform())
+                            .setDirection(ctr_transform_invert == 1);
+                }
+
+                /* No output transforms are defined the DLS Level 2
+                int out_transform = transform % 8;
+                int trans = ModelStandardTransform.TRANSFORM_LINEAR;
+                if (out_transform == DLSModulator.CONN_TRN_SWITCH)
+                    trans = ModelStandardTransform.TRANSFORM_SWITCH;
+                if (out_transform == DLSModulator.CONN_TRN_CONCAVE)
+                    trans = ModelStandardTransform.TRANSFORM_CONCAVE;
+                if (out_transform == DLSModulator.CONN_TRN_CONVEX)
+                    trans = ModelStandardTransform.TRANSFORM_CONVEX;
+                if (ctrl != null) {
+                    ((ModelStandardTransform)destination.getTransform())
+                            .setTransform(trans);
+                }
+                */
+
+            }
+
+            block.setScale(f_scale);
+
+            return block;
+        }
+
+        return null;
+    }
+
+    public ModelPerformer[] getPerformers() {
+        List<ModelPerformer> performers = new ArrayList<ModelPerformer>();
+
+        Map<String, DLSModulator> modmap = new HashMap<String, DLSModulator>();
+        for (DLSModulator mod: getModulators()) {
+            modmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
+                    mod.getDestination(), mod);
+        }
+
+        Map<String, DLSModulator> insmodmap =
+                new HashMap<String, DLSModulator>();
+
+        for (DLSRegion zone: regions) {
+            ModelPerformer performer = new ModelPerformer();
+            performer.setName(zone.getSample().getName());
+            performer.setSelfNonExclusive((zone.getFusoptions() &
+                    DLSRegion.OPTION_SELFNONEXCLUSIVE) != 0);
+            performer.setExclusiveClass(zone.getExclusiveClass());
+            performer.setKeyFrom(zone.getKeyfrom());
+            performer.setKeyTo(zone.getKeyto());
+            performer.setVelFrom(zone.getVelfrom());
+            performer.setVelTo(zone.getVelto());
+
+            insmodmap.clear();
+            insmodmap.putAll(modmap);
+            for (DLSModulator mod: zone.getModulators()) {
+                insmodmap.put(mod.getSource() + "x" + mod.getControl() + "=" +
+                        mod.getDestination(), mod);
+            }
+
+            List<ModelConnectionBlock> blocks = performer.getConnectionBlocks();
+            for (DLSModulator mod: insmodmap.values()) {
+                ModelConnectionBlock p = convertToModel(mod);
+                if (p != null)
+                    blocks.add(p);
+            }
+
+
+            DLSSample sample = zone.getSample();
+            DLSSampleOptions sampleopt = zone.getSampleoptions();
+            if (sampleopt == null)
+                sampleopt = sample.getSampleoptions();
+
+            ModelByteBuffer buff = sample.getDataBuffer();
+
+            float pitchcorrection = (-sampleopt.unitynote * 100) +
+                    sampleopt.finetune;
+
+            ModelByteBufferWavetable osc = new ModelByteBufferWavetable(buff,
+                    sample.getFormat(), pitchcorrection);
+            osc.setAttenuation(osc.getAttenuation() / 65536f);
+            if (sampleopt.getLoops().size() != 0) {
+                DLSSampleLoop loop = sampleopt.getLoops().get(0);
+                osc.setLoopStart((int)loop.getStart());
+                osc.setLoopLength((int)loop.getLength());
+                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_FORWARD)
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+                if (loop.getType() == DLSSampleLoop.LOOP_TYPE_RELEASE)
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
+                else
+                    osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+            }
+
+            performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(SoftFilter.FILTERTYPE_LP12,
+                        new ModelDestination(
+                            new ModelIdentifier("filter", "type", 1))));
+
+            performer.getOscillators().add(osc);
+
+            performers.add(performer);
+
+        }
+
+        return performers.toArray(new ModelPerformer[performers.size()]);
+    }
+
+    public byte[] getGuid() {
+        return guid;
+    }
+
+    public void setGuid(byte[] guid) {
+        this.guid = guid;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSModulator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSModulator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,351 +1,351 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This class is used to store modulator/artiuclation data.
- * A modulator connects one synthesizer source to
- * a destination. For example a note on velocity
- * can be mapped to the gain of the synthesized voice.
- * It is stored as a "art1" or "art2" chunk inside DLS files.
- *
- * @author Karl Helgason
- */
-public class DLSModulator {
-
-    // DLS1 Destinations
-    public static final int CONN_DST_NONE = 0x000; // 0
-    public static final int CONN_DST_GAIN = 0x001; // cB
-    public static final int CONN_DST_PITCH = 0x003; // cent
-    public static final int CONN_DST_PAN = 0x004; // 0.1%
-    public static final int CONN_DST_LFO_FREQUENCY = 0x104; // cent (default 5 Hz)
-    public static final int CONN_DST_LFO_STARTDELAY = 0x105; // timecent
-    public static final int CONN_DST_EG1_ATTACKTIME = 0x206; // timecent
-    public static final int CONN_DST_EG1_DECAYTIME = 0x207; // timecent
-    public static final int CONN_DST_EG1_RELEASETIME = 0x209; // timecent
-    public static final int CONN_DST_EG1_SUSTAINLEVEL = 0x20A; // 0.1%
-    public static final int CONN_DST_EG2_ATTACKTIME = 0x30A; // timecent
-    public static final int CONN_DST_EG2_DECAYTIME = 0x30B; // timecent
-    public static final int CONN_DST_EG2_RELEASETIME = 0x30D; // timecent
-    public static final int CONN_DST_EG2_SUSTAINLEVEL = 0x30E; // 0.1%
-    // DLS2 Destinations
-    public static final int CONN_DST_KEYNUMBER = 0x005;
-    public static final int CONN_DST_LEFT = 0x010; // 0.1%
-    public static final int CONN_DST_RIGHT = 0x011; // 0.1%
-    public static final int CONN_DST_CENTER = 0x012; // 0.1%
-    public static final int CONN_DST_LEFTREAR = 0x013; // 0.1%
-    public static final int CONN_DST_RIGHTREAR = 0x014; // 0.1%
-    public static final int CONN_DST_LFE_CHANNEL = 0x015; // 0.1%
-    public static final int CONN_DST_CHORUS = 0x080; // 0.1%
-    public static final int CONN_DST_REVERB = 0x081; // 0.1%
-    public static final int CONN_DST_VIB_FREQUENCY = 0x114; // cent
-    public static final int CONN_DST_VIB_STARTDELAY = 0x115; // dB
-    public static final int CONN_DST_EG1_DELAYTIME = 0x20B; // timecent
-    public static final int CONN_DST_EG1_HOLDTIME = 0x20C; // timecent
-    public static final int CONN_DST_EG1_SHUTDOWNTIME = 0x20D; // timecent
-    public static final int CONN_DST_EG2_DELAYTIME = 0x30F; // timecent
-    public static final int CONN_DST_EG2_HOLDTIME = 0x310; // timecent
-    public static final int CONN_DST_FILTER_CUTOFF = 0x500; // cent
-    public static final int CONN_DST_FILTER_Q = 0x501; // dB
-
-    // DLS1 Sources
-    public static final int CONN_SRC_NONE = 0x000; // 1
-    public static final int CONN_SRC_LFO = 0x001; // linear (sine wave)
-    public static final int CONN_SRC_KEYONVELOCITY = 0x002; // ??db or velocity??
-    public static final int CONN_SRC_KEYNUMBER = 0x003; // ??cent or keynumber??
-    public static final int CONN_SRC_EG1 = 0x004; // linear direct from eg
-    public static final int CONN_SRC_EG2 = 0x005; // linear direct from eg
-    public static final int CONN_SRC_PITCHWHEEL = 0x006; // linear -1..1
-    public static final int CONN_SRC_CC1 = 0x081; // linear 0..1
-    public static final int CONN_SRC_CC7 = 0x087; // linear 0..1
-    public static final int CONN_SRC_CC10 = 0x08A; // linear 0..1
-    public static final int CONN_SRC_CC11 = 0x08B; // linear 0..1
-    public static final int CONN_SRC_RPN0 = 0x100; // ?? // Pitch Bend Range
-    public static final int CONN_SRC_RPN1 = 0x101; // ?? // Fine Tune
-    public static final int CONN_SRC_RPN2 = 0x102; // ?? // Course Tune
-    // DLS2 Sources
-    public static final int CONN_SRC_POLYPRESSURE = 0x007; // linear 0..1
-    public static final int CONN_SRC_CHANNELPRESSURE = 0x008; // linear 0..1
-    public static final int CONN_SRC_VIBRATO = 0x009; // linear 0..1
-    public static final int CONN_SRC_MONOPRESSURE = 0x00A; // linear 0..1
-    public static final int CONN_SRC_CC91 = 0x0DB; // linear 0..1
-    public static final int CONN_SRC_CC93 = 0x0DD; // linear 0..1
-    // DLS1 Transforms
-    public static final int CONN_TRN_NONE = 0x000;
-    public static final int CONN_TRN_CONCAVE = 0x001;
-    // DLS2 Transforms
-    public static final int CONN_TRN_CONVEX = 0x002;
-    public static final int CONN_TRN_SWITCH = 0x003;
-    public static final int DST_FORMAT_CB = 1;
-    public static final int DST_FORMAT_CENT = 1;
-    public static final int DST_FORMAT_TIMECENT = 2;
-    public static final int DST_FORMAT_PERCENT = 3;
-    protected int source;
-    protected int control;
-    protected int destination;
-    protected int transform;
-    protected int scale;
-    protected int version = 1;
-
-    public int getControl() {
-        return control;
-    }
-
-    public void setControl(int control) {
-        this.control = control;
-    }
-
-    public static int getDestinationFormat(int destination) {
-
-        if (destination == CONN_DST_GAIN)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_PITCH)
-            return DST_FORMAT_CENT;
-        if (destination == CONN_DST_PAN)
-            return DST_FORMAT_PERCENT;
-
-        if (destination == CONN_DST_LFO_FREQUENCY)
-            return DST_FORMAT_CENT;
-        if (destination == CONN_DST_LFO_STARTDELAY)
-            return DST_FORMAT_TIMECENT;
-
-        if (destination == CONN_DST_EG1_ATTACKTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG1_DECAYTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG1_RELEASETIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
-            return DST_FORMAT_PERCENT;
-
-        if (destination == CONN_DST_EG2_ATTACKTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG2_DECAYTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG2_RELEASETIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
-            return DST_FORMAT_PERCENT;
-
-        if (destination == CONN_DST_KEYNUMBER)
-            return DST_FORMAT_CENT; // NOT SURE WITHOUT DLS 2 SPEC
-        if (destination == CONN_DST_LEFT)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_RIGHT)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_CENTER)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_LEFTREAR)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_RIGHTREAR)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_LFE_CHANNEL)
-            return DST_FORMAT_CB;
-        if (destination == CONN_DST_CHORUS)
-            return DST_FORMAT_PERCENT;
-        if (destination == CONN_DST_REVERB)
-            return DST_FORMAT_PERCENT;
-
-        if (destination == CONN_DST_VIB_FREQUENCY)
-            return DST_FORMAT_CENT;
-        if (destination == CONN_DST_VIB_STARTDELAY)
-            return DST_FORMAT_TIMECENT;
-
-        if (destination == CONN_DST_EG1_DELAYTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG1_HOLDTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
-            return DST_FORMAT_TIMECENT;
-
-        if (destination == CONN_DST_EG2_DELAYTIME)
-            return DST_FORMAT_TIMECENT;
-        if (destination == CONN_DST_EG2_HOLDTIME)
-            return DST_FORMAT_TIMECENT;
-
-        if (destination == CONN_DST_FILTER_CUTOFF)
-            return DST_FORMAT_CENT;
-        if (destination == CONN_DST_FILTER_Q)
-            return DST_FORMAT_CB;
-
-        return -1;
-    }
-
-    public static String getDestinationName(int destination) {
-
-        if (destination == CONN_DST_GAIN)
-            return "gain";
-        if (destination == CONN_DST_PITCH)
-            return "pitch";
-        if (destination == CONN_DST_PAN)
-            return "pan";
-
-        if (destination == CONN_DST_LFO_FREQUENCY)
-            return "lfo1.freq";
-        if (destination == CONN_DST_LFO_STARTDELAY)
-            return "lfo1.delay";
-
-        if (destination == CONN_DST_EG1_ATTACKTIME)
-            return "eg1.attack";
-        if (destination == CONN_DST_EG1_DECAYTIME)
-            return "eg1.decay";
-        if (destination == CONN_DST_EG1_RELEASETIME)
-            return "eg1.release";
-        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
-            return "eg1.sustain";
-
-        if (destination == CONN_DST_EG2_ATTACKTIME)
-            return "eg2.attack";
-        if (destination == CONN_DST_EG2_DECAYTIME)
-            return "eg2.decay";
-        if (destination == CONN_DST_EG2_RELEASETIME)
-            return "eg2.release";
-        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
-            return "eg2.sustain";
-
-        if (destination == CONN_DST_KEYNUMBER)
-            return "keynumber";
-        if (destination == CONN_DST_LEFT)
-            return "left";
-        if (destination == CONN_DST_RIGHT)
-            return "right";
-        if (destination == CONN_DST_CENTER)
-            return "center";
-        if (destination == CONN_DST_LEFTREAR)
-            return "leftrear";
-        if (destination == CONN_DST_RIGHTREAR)
-            return "rightrear";
-        if (destination == CONN_DST_LFE_CHANNEL)
-            return "lfe_channel";
-        if (destination == CONN_DST_CHORUS)
-            return "chorus";
-        if (destination == CONN_DST_REVERB)
-            return "reverb";
-
-        if (destination == CONN_DST_VIB_FREQUENCY)
-            return "vib.freq";
-        if (destination == CONN_DST_VIB_STARTDELAY)
-            return "vib.delay";
-
-        if (destination == CONN_DST_EG1_DELAYTIME)
-            return "eg1.delay";
-        if (destination == CONN_DST_EG1_HOLDTIME)
-            return "eg1.hold";
-        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
-            return "eg1.shutdown";
-
-        if (destination == CONN_DST_EG2_DELAYTIME)
-            return "eg2.delay";
-        if (destination == CONN_DST_EG2_HOLDTIME)
-            return "eg.2hold";
-
-        if (destination == CONN_DST_FILTER_CUTOFF)
-            return "filter.cutoff"; // NOT SURE WITHOUT DLS 2 SPEC
-        if (destination == CONN_DST_FILTER_Q)
-            return "filter.q"; // NOT SURE WITHOUT DLS 2 SPEC
-
-        return null;
-    }
-
-    public static String getSourceName(int source) {
-
-        if (source == CONN_SRC_NONE)
-            return "none";
-        if (source == CONN_SRC_LFO)
-            return "lfo";
-        if (source == CONN_SRC_KEYONVELOCITY)
-            return "keyonvelocity";
-        if (source == CONN_SRC_KEYNUMBER)
-            return "keynumber";
-        if (source == CONN_SRC_EG1)
-            return "eg1";
-        if (source == CONN_SRC_EG2)
-            return "eg2";
-        if (source == CONN_SRC_PITCHWHEEL)
-            return "pitchweel";
-        if (source == CONN_SRC_CC1)
-            return "cc1";
-        if (source == CONN_SRC_CC7)
-            return "cc7";
-        if (source == CONN_SRC_CC10)
-            return "c10";
-        if (source == CONN_SRC_CC11)
-            return "cc11";
-
-        if (source == CONN_SRC_POLYPRESSURE)
-            return "polypressure";
-        if (source == CONN_SRC_CHANNELPRESSURE)
-            return "channelpressure";
-        if (source == CONN_SRC_VIBRATO)
-            return "vibrato";
-        if (source == CONN_SRC_MONOPRESSURE)
-            return "monopressure";
-        if (source == CONN_SRC_CC91)
-            return "cc91";
-        if (source == CONN_SRC_CC93)
-            return "cc93";
-        return null;
-    }
-
-    public int getDestination() {
-        return destination;
-    }
-
-    public void setDestination(int destination) {
-        this.destination = destination;
-    }
-
-    public int getScale() {
-        return scale;
-    }
-
-    public void setScale(int scale) {
-        this.scale = scale;
-    }
-
-    public int getSource() {
-        return source;
-    }
-
-    public void setSource(int source) {
-        this.source = source;
-    }
-
-    public int getVersion() {
-        return version;
-    }
-
-    public void setVersion(int version) {
-        this.version = version;
-    }
-
-    public int getTransform() {
-        return transform;
-    }
-
-    public void setTransform(int transform) {
-        this.transform = transform;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store modulator/artiuclation data.
+ * A modulator connects one synthesizer source to
+ * a destination. For example a note on velocity
+ * can be mapped to the gain of the synthesized voice.
+ * It is stored as a "art1" or "art2" chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSModulator {
+
+    // DLS1 Destinations
+    public static final int CONN_DST_NONE = 0x000; // 0
+    public static final int CONN_DST_GAIN = 0x001; // cB
+    public static final int CONN_DST_PITCH = 0x003; // cent
+    public static final int CONN_DST_PAN = 0x004; // 0.1%
+    public static final int CONN_DST_LFO_FREQUENCY = 0x104; // cent (default 5 Hz)
+    public static final int CONN_DST_LFO_STARTDELAY = 0x105; // timecent
+    public static final int CONN_DST_EG1_ATTACKTIME = 0x206; // timecent
+    public static final int CONN_DST_EG1_DECAYTIME = 0x207; // timecent
+    public static final int CONN_DST_EG1_RELEASETIME = 0x209; // timecent
+    public static final int CONN_DST_EG1_SUSTAINLEVEL = 0x20A; // 0.1%
+    public static final int CONN_DST_EG2_ATTACKTIME = 0x30A; // timecent
+    public static final int CONN_DST_EG2_DECAYTIME = 0x30B; // timecent
+    public static final int CONN_DST_EG2_RELEASETIME = 0x30D; // timecent
+    public static final int CONN_DST_EG2_SUSTAINLEVEL = 0x30E; // 0.1%
+    // DLS2 Destinations
+    public static final int CONN_DST_KEYNUMBER = 0x005;
+    public static final int CONN_DST_LEFT = 0x010; // 0.1%
+    public static final int CONN_DST_RIGHT = 0x011; // 0.1%
+    public static final int CONN_DST_CENTER = 0x012; // 0.1%
+    public static final int CONN_DST_LEFTREAR = 0x013; // 0.1%
+    public static final int CONN_DST_RIGHTREAR = 0x014; // 0.1%
+    public static final int CONN_DST_LFE_CHANNEL = 0x015; // 0.1%
+    public static final int CONN_DST_CHORUS = 0x080; // 0.1%
+    public static final int CONN_DST_REVERB = 0x081; // 0.1%
+    public static final int CONN_DST_VIB_FREQUENCY = 0x114; // cent
+    public static final int CONN_DST_VIB_STARTDELAY = 0x115; // dB
+    public static final int CONN_DST_EG1_DELAYTIME = 0x20B; // timecent
+    public static final int CONN_DST_EG1_HOLDTIME = 0x20C; // timecent
+    public static final int CONN_DST_EG1_SHUTDOWNTIME = 0x20D; // timecent
+    public static final int CONN_DST_EG2_DELAYTIME = 0x30F; // timecent
+    public static final int CONN_DST_EG2_HOLDTIME = 0x310; // timecent
+    public static final int CONN_DST_FILTER_CUTOFF = 0x500; // cent
+    public static final int CONN_DST_FILTER_Q = 0x501; // dB
+
+    // DLS1 Sources
+    public static final int CONN_SRC_NONE = 0x000; // 1
+    public static final int CONN_SRC_LFO = 0x001; // linear (sine wave)
+    public static final int CONN_SRC_KEYONVELOCITY = 0x002; // ??db or velocity??
+    public static final int CONN_SRC_KEYNUMBER = 0x003; // ??cent or keynumber??
+    public static final int CONN_SRC_EG1 = 0x004; // linear direct from eg
+    public static final int CONN_SRC_EG2 = 0x005; // linear direct from eg
+    public static final int CONN_SRC_PITCHWHEEL = 0x006; // linear -1..1
+    public static final int CONN_SRC_CC1 = 0x081; // linear 0..1
+    public static final int CONN_SRC_CC7 = 0x087; // linear 0..1
+    public static final int CONN_SRC_CC10 = 0x08A; // linear 0..1
+    public static final int CONN_SRC_CC11 = 0x08B; // linear 0..1
+    public static final int CONN_SRC_RPN0 = 0x100; // ?? // Pitch Bend Range
+    public static final int CONN_SRC_RPN1 = 0x101; // ?? // Fine Tune
+    public static final int CONN_SRC_RPN2 = 0x102; // ?? // Course Tune
+    // DLS2 Sources
+    public static final int CONN_SRC_POLYPRESSURE = 0x007; // linear 0..1
+    public static final int CONN_SRC_CHANNELPRESSURE = 0x008; // linear 0..1
+    public static final int CONN_SRC_VIBRATO = 0x009; // linear 0..1
+    public static final int CONN_SRC_MONOPRESSURE = 0x00A; // linear 0..1
+    public static final int CONN_SRC_CC91 = 0x0DB; // linear 0..1
+    public static final int CONN_SRC_CC93 = 0x0DD; // linear 0..1
+    // DLS1 Transforms
+    public static final int CONN_TRN_NONE = 0x000;
+    public static final int CONN_TRN_CONCAVE = 0x001;
+    // DLS2 Transforms
+    public static final int CONN_TRN_CONVEX = 0x002;
+    public static final int CONN_TRN_SWITCH = 0x003;
+    public static final int DST_FORMAT_CB = 1;
+    public static final int DST_FORMAT_CENT = 1;
+    public static final int DST_FORMAT_TIMECENT = 2;
+    public static final int DST_FORMAT_PERCENT = 3;
+    protected int source;
+    protected int control;
+    protected int destination;
+    protected int transform;
+    protected int scale;
+    protected int version = 1;
+
+    public int getControl() {
+        return control;
+    }
+
+    public void setControl(int control) {
+        this.control = control;
+    }
+
+    public static int getDestinationFormat(int destination) {
+
+        if (destination == CONN_DST_GAIN)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_PITCH)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_PAN)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_LFO_FREQUENCY)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_LFO_STARTDELAY)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG1_ATTACKTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_DECAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_RELEASETIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_EG2_ATTACKTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_DECAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_RELEASETIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_KEYNUMBER)
+            return DST_FORMAT_CENT; // NOT SURE WITHOUT DLS 2 SPEC
+        if (destination == CONN_DST_LEFT)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_RIGHT)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_CENTER)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_LEFTREAR)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_RIGHTREAR)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_LFE_CHANNEL)
+            return DST_FORMAT_CB;
+        if (destination == CONN_DST_CHORUS)
+            return DST_FORMAT_PERCENT;
+        if (destination == CONN_DST_REVERB)
+            return DST_FORMAT_PERCENT;
+
+        if (destination == CONN_DST_VIB_FREQUENCY)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_VIB_STARTDELAY)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG1_DELAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_HOLDTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_EG2_DELAYTIME)
+            return DST_FORMAT_TIMECENT;
+        if (destination == CONN_DST_EG2_HOLDTIME)
+            return DST_FORMAT_TIMECENT;
+
+        if (destination == CONN_DST_FILTER_CUTOFF)
+            return DST_FORMAT_CENT;
+        if (destination == CONN_DST_FILTER_Q)
+            return DST_FORMAT_CB;
+
+        return -1;
+    }
+
+    public static String getDestinationName(int destination) {
+
+        if (destination == CONN_DST_GAIN)
+            return "gain";
+        if (destination == CONN_DST_PITCH)
+            return "pitch";
+        if (destination == CONN_DST_PAN)
+            return "pan";
+
+        if (destination == CONN_DST_LFO_FREQUENCY)
+            return "lfo1.freq";
+        if (destination == CONN_DST_LFO_STARTDELAY)
+            return "lfo1.delay";
+
+        if (destination == CONN_DST_EG1_ATTACKTIME)
+            return "eg1.attack";
+        if (destination == CONN_DST_EG1_DECAYTIME)
+            return "eg1.decay";
+        if (destination == CONN_DST_EG1_RELEASETIME)
+            return "eg1.release";
+        if (destination == CONN_DST_EG1_SUSTAINLEVEL)
+            return "eg1.sustain";
+
+        if (destination == CONN_DST_EG2_ATTACKTIME)
+            return "eg2.attack";
+        if (destination == CONN_DST_EG2_DECAYTIME)
+            return "eg2.decay";
+        if (destination == CONN_DST_EG2_RELEASETIME)
+            return "eg2.release";
+        if (destination == CONN_DST_EG2_SUSTAINLEVEL)
+            return "eg2.sustain";
+
+        if (destination == CONN_DST_KEYNUMBER)
+            return "keynumber";
+        if (destination == CONN_DST_LEFT)
+            return "left";
+        if (destination == CONN_DST_RIGHT)
+            return "right";
+        if (destination == CONN_DST_CENTER)
+            return "center";
+        if (destination == CONN_DST_LEFTREAR)
+            return "leftrear";
+        if (destination == CONN_DST_RIGHTREAR)
+            return "rightrear";
+        if (destination == CONN_DST_LFE_CHANNEL)
+            return "lfe_channel";
+        if (destination == CONN_DST_CHORUS)
+            return "chorus";
+        if (destination == CONN_DST_REVERB)
+            return "reverb";
+
+        if (destination == CONN_DST_VIB_FREQUENCY)
+            return "vib.freq";
+        if (destination == CONN_DST_VIB_STARTDELAY)
+            return "vib.delay";
+
+        if (destination == CONN_DST_EG1_DELAYTIME)
+            return "eg1.delay";
+        if (destination == CONN_DST_EG1_HOLDTIME)
+            return "eg1.hold";
+        if (destination == CONN_DST_EG1_SHUTDOWNTIME)
+            return "eg1.shutdown";
+
+        if (destination == CONN_DST_EG2_DELAYTIME)
+            return "eg2.delay";
+        if (destination == CONN_DST_EG2_HOLDTIME)
+            return "eg.2hold";
+
+        if (destination == CONN_DST_FILTER_CUTOFF)
+            return "filter.cutoff"; // NOT SURE WITHOUT DLS 2 SPEC
+        if (destination == CONN_DST_FILTER_Q)
+            return "filter.q"; // NOT SURE WITHOUT DLS 2 SPEC
+
+        return null;
+    }
+
+    public static String getSourceName(int source) {
+
+        if (source == CONN_SRC_NONE)
+            return "none";
+        if (source == CONN_SRC_LFO)
+            return "lfo";
+        if (source == CONN_SRC_KEYONVELOCITY)
+            return "keyonvelocity";
+        if (source == CONN_SRC_KEYNUMBER)
+            return "keynumber";
+        if (source == CONN_SRC_EG1)
+            return "eg1";
+        if (source == CONN_SRC_EG2)
+            return "eg2";
+        if (source == CONN_SRC_PITCHWHEEL)
+            return "pitchweel";
+        if (source == CONN_SRC_CC1)
+            return "cc1";
+        if (source == CONN_SRC_CC7)
+            return "cc7";
+        if (source == CONN_SRC_CC10)
+            return "c10";
+        if (source == CONN_SRC_CC11)
+            return "cc11";
+
+        if (source == CONN_SRC_POLYPRESSURE)
+            return "polypressure";
+        if (source == CONN_SRC_CHANNELPRESSURE)
+            return "channelpressure";
+        if (source == CONN_SRC_VIBRATO)
+            return "vibrato";
+        if (source == CONN_SRC_MONOPRESSURE)
+            return "monopressure";
+        if (source == CONN_SRC_CC91)
+            return "cc91";
+        if (source == CONN_SRC_CC93)
+            return "cc93";
+        return null;
+    }
+
+    public int getDestination() {
+        return destination;
+    }
+
+    public void setDestination(int destination) {
+        this.destination = destination;
+    }
+
+    public int getScale() {
+        return scale;
+    }
+
+    public void setScale(int scale) {
+        this.scale = scale;
+    }
+
+    public int getSource() {
+        return source;
+    }
+
+    public void setSource(int source) {
+        this.source = source;
+    }
+
+    public int getVersion() {
+        return version;
+    }
+
+    public void setVersion(int version) {
+        this.version = version;
+    }
+
+    public int getTransform() {
+        return transform;
+    }
+
+    public void setTransform(int transform) {
+        this.transform = transform;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSRegion.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSRegion.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,150 +1,150 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class is used to store region parts for instrument.
- * A region has a velocity and key range which it response to.
- * And it has a list of modulators/articulators which
- * is used how to synthesize a single voice.
- * It is stored inside a "rgn " List Chunk inside DLS files.
- *
- * @author Karl Helgason
- */
-public class DLSRegion {
-
-    public final static int OPTION_SELFNONEXCLUSIVE = 0x0001;
-    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
-    protected int keyfrom;
-    protected int keyto;
-    protected int velfrom;
-    protected int velto;
-    protected int options;
-    protected int exclusiveClass;
-    protected int fusoptions;
-    protected int phasegroup;
-    protected long channel;
-    protected DLSSample sample = null;
-    protected DLSSampleOptions sampleoptions;
-
-    public List<DLSModulator> getModulators() {
-        return modulators;
-    }
-
-    public long getChannel() {
-        return channel;
-    }
-
-    public void setChannel(long channel) {
-        this.channel = channel;
-    }
-
-    public int getExclusiveClass() {
-        return exclusiveClass;
-    }
-
-    public void setExclusiveClass(int exclusiveClass) {
-        this.exclusiveClass = exclusiveClass;
-    }
-
-    public int getFusoptions() {
-        return fusoptions;
-    }
-
-    public void setFusoptions(int fusoptions) {
-        this.fusoptions = fusoptions;
-    }
-
-    public int getKeyfrom() {
-        return keyfrom;
-    }
-
-    public void setKeyfrom(int keyfrom) {
-        this.keyfrom = keyfrom;
-    }
-
-    public int getKeyto() {
-        return keyto;
-    }
-
-    public void setKeyto(int keyto) {
-        this.keyto = keyto;
-    }
-
-    public int getOptions() {
-        return options;
-    }
-
-    public void setOptions(int options) {
-        this.options = options;
-    }
-
-    public int getPhasegroup() {
-        return phasegroup;
-    }
-
-    public void setPhasegroup(int phasegroup) {
-        this.phasegroup = phasegroup;
-    }
-
-    public DLSSample getSample() {
-        return sample;
-    }
-
-    public void setSample(DLSSample sample) {
-        this.sample = sample;
-    }
-
-    public int getVelfrom() {
-        return velfrom;
-    }
-
-    public void setVelfrom(int velfrom) {
-        this.velfrom = velfrom;
-    }
-
-    public int getVelto() {
-        return velto;
-    }
-
-    public void setVelto(int velto) {
-        this.velto = velto;
-    }
-
-    public void setModulators(List<DLSModulator> modulators) {
-        this.modulators = modulators;
-    }
-
-    public DLSSampleOptions getSampleoptions() {
-        return sampleoptions;
-    }
-
-    public void setSampleoptions(DLSSampleOptions sampleOptions) {
-        this.sampleoptions = sampleOptions;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used to store region parts for instrument.
+ * A region has a velocity and key range which it response to.
+ * And it has a list of modulators/articulators which
+ * is used how to synthesize a single voice.
+ * It is stored inside a "rgn " List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSRegion {
+
+    public final static int OPTION_SELFNONEXCLUSIVE = 0x0001;
+    protected List<DLSModulator> modulators = new ArrayList<DLSModulator>();
+    protected int keyfrom;
+    protected int keyto;
+    protected int velfrom;
+    protected int velto;
+    protected int options;
+    protected int exclusiveClass;
+    protected int fusoptions;
+    protected int phasegroup;
+    protected long channel;
+    protected DLSSample sample = null;
+    protected DLSSampleOptions sampleoptions;
+
+    public List<DLSModulator> getModulators() {
+        return modulators;
+    }
+
+    public long getChannel() {
+        return channel;
+    }
+
+    public void setChannel(long channel) {
+        this.channel = channel;
+    }
+
+    public int getExclusiveClass() {
+        return exclusiveClass;
+    }
+
+    public void setExclusiveClass(int exclusiveClass) {
+        this.exclusiveClass = exclusiveClass;
+    }
+
+    public int getFusoptions() {
+        return fusoptions;
+    }
+
+    public void setFusoptions(int fusoptions) {
+        this.fusoptions = fusoptions;
+    }
+
+    public int getKeyfrom() {
+        return keyfrom;
+    }
+
+    public void setKeyfrom(int keyfrom) {
+        this.keyfrom = keyfrom;
+    }
+
+    public int getKeyto() {
+        return keyto;
+    }
+
+    public void setKeyto(int keyto) {
+        this.keyto = keyto;
+    }
+
+    public int getOptions() {
+        return options;
+    }
+
+    public void setOptions(int options) {
+        this.options = options;
+    }
+
+    public int getPhasegroup() {
+        return phasegroup;
+    }
+
+    public void setPhasegroup(int phasegroup) {
+        this.phasegroup = phasegroup;
+    }
+
+    public DLSSample getSample() {
+        return sample;
+    }
+
+    public void setSample(DLSSample sample) {
+        this.sample = sample;
+    }
+
+    public int getVelfrom() {
+        return velfrom;
+    }
+
+    public void setVelfrom(int velfrom) {
+        this.velfrom = velfrom;
+    }
+
+    public int getVelto() {
+        return velto;
+    }
+
+    public void setVelto(int velto) {
+        this.velto = velto;
+    }
+
+    public void setModulators(List<DLSModulator> modulators) {
+        this.modulators = modulators;
+    }
+
+    public DLSSampleOptions getSampleoptions() {
+        return sampleoptions;
+    }
+
+    public void setSampleoptions(DLSSampleOptions sampleOptions) {
+        this.sampleoptions = sampleOptions;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSSample.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSample.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,122 +1,122 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.InputStream;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.SoundbankResource;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-
-/**
- * This class is used to store the sample data itself.
- * A sample is encoded as PCM audio stream
- * and in DLS Level 1 files it is always a mono 8/16 bit stream.
- * They are stored just like RIFF WAVE files are stored.
- * It is stored inside a "wave" List Chunk inside DLS files.
- *
- * @author Karl Helgason
- */
-public class DLSSample extends SoundbankResource {
-
-    protected byte[] guid = null;
-    protected DLSInfo info = new DLSInfo();
-    protected DLSSampleOptions sampleoptions;
-    protected ModelByteBuffer data;
-    protected AudioFormat format;
-
-    public DLSSample(Soundbank soundBank) {
-        super(soundBank, null, AudioInputStream.class);
-    }
-
-    public DLSSample() {
-        super(null, null, AudioInputStream.class);
-    }
-
-    public DLSInfo getInfo() {
-        return info;
-    }
-
-    public Object getData() {
-        AudioFormat format = getFormat();
-
-        InputStream is = data.getInputStream();
-        if (is == null)
-            return null;
-        return new AudioInputStream(is, format, data.capacity());
-    }
-
-    public ModelByteBuffer getDataBuffer() {
-        return data;
-    }
-
-    public AudioFormat getFormat() {
-        return format;
-    }
-
-    public void setFormat(AudioFormat format) {
-        this.format = format;
-    }
-
-    public void setData(ModelByteBuffer data) {
-        this.data = data;
-    }
-
-    public void setData(byte[] data) {
-        this.data = new ModelByteBuffer(data);
-    }
-
-    public void setData(byte[] data, int offset, int length) {
-        this.data = new ModelByteBuffer(data, offset, length);
-    }
-
-    public String getName() {
-        return info.name;
-    }
-
-    public void setName(String name) {
-        info.name = name;
-    }
-
-    public DLSSampleOptions getSampleoptions() {
-        return sampleoptions;
-    }
-
-    public void setSampleoptions(DLSSampleOptions sampleOptions) {
-        this.sampleoptions = sampleOptions;
-    }
-
-    public String toString() {
-        return "Sample: " + info.name;
-    }
-
-    public byte[] getGuid() {
-        return guid;
-    }
-
-    public void setGuid(byte[] guid) {
-        this.guid = guid;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.InputStream;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * This class is used to store the sample data itself.
+ * A sample is encoded as PCM audio stream
+ * and in DLS Level 1 files it is always a mono 8/16 bit stream.
+ * They are stored just like RIFF WAVE files are stored.
+ * It is stored inside a "wave" List Chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSample extends SoundbankResource {
+
+    protected byte[] guid = null;
+    protected DLSInfo info = new DLSInfo();
+    protected DLSSampleOptions sampleoptions;
+    protected ModelByteBuffer data;
+    protected AudioFormat format;
+
+    public DLSSample(Soundbank soundBank) {
+        super(soundBank, null, AudioInputStream.class);
+    }
+
+    public DLSSample() {
+        super(null, null, AudioInputStream.class);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public Object getData() {
+        AudioFormat format = getFormat();
+
+        InputStream is = data.getInputStream();
+        if (is == null)
+            return null;
+        return new AudioInputStream(is, format, data.capacity());
+    }
+
+    public ModelByteBuffer getDataBuffer() {
+        return data;
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public void setFormat(AudioFormat format) {
+        this.format = format;
+    }
+
+    public void setData(ModelByteBuffer data) {
+        this.data = data;
+    }
+
+    public void setData(byte[] data) {
+        this.data = new ModelByteBuffer(data);
+    }
+
+    public void setData(byte[] data, int offset, int length) {
+        this.data = new ModelByteBuffer(data, offset, length);
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public void setName(String name) {
+        info.name = name;
+    }
+
+    public DLSSampleOptions getSampleoptions() {
+        return sampleoptions;
+    }
+
+    public void setSampleoptions(DLSSampleOptions sampleOptions) {
+        this.sampleoptions = sampleOptions;
+    }
+
+    public String toString() {
+        return "Sample: " + info.name;
+    }
+
+    public byte[] getGuid() {
+        return guid;
+    }
+
+    public void setGuid(byte[] guid) {
+        this.guid = guid;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSampleLoop.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,63 +1,63 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This class is used to store loop points inside DLSSampleOptions class.
- *
- * @author Karl Helgason
- */
-public class DLSSampleLoop {
-
-    public final static int LOOP_TYPE_FORWARD = 0;
-    public final static int LOOP_TYPE_RELEASE = 1;
-    protected long type;
-    protected long start;
-    protected long length;
-
-    public long getLength() {
-        return length;
-    }
-
-    public void setLength(long length) {
-        this.length = length;
-    }
-
-    public long getStart() {
-        return start;
-    }
-
-    public void setStart(long start) {
-        this.start = start;
-    }
-
-    public long getType() {
-        return type;
-    }
-
-    public void setType(long type) {
-        this.type = type;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to store loop points inside DLSSampleOptions class.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSampleLoop {
+
+    public final static int LOOP_TYPE_FORWARD = 0;
+    public final static int LOOP_TYPE_RELEASE = 1;
+    protected long type;
+    protected long start;
+    protected long length;
+
+    public long getLength() {
+        return length;
+    }
+
+    public void setLength(long length) {
+        this.length = length;
+    }
+
+    public long getStart() {
+        return start;
+    }
+
+    public void setStart(long start) {
+        this.start = start;
+    }
+
+    public long getType() {
+        return type;
+    }
+
+    public void setType(long type) {
+        this.type = type;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSampleOptions.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,80 +1,80 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class stores options how to playback sampled data like pitch/tuning,
- * attenuation and loops.
- * It is stored as a "wsmp" chunk inside DLS files.
- *
- * @author Karl Helgason
- */
-public class DLSSampleOptions {
-
-    protected int unitynote;
-    protected short finetune;
-    protected int attenuation;
-    protected long options;
-    protected List<DLSSampleLoop> loops = new ArrayList<DLSSampleLoop>();
-
-    public int getAttenuation() {
-        return attenuation;
-    }
-
-    public void setAttenuation(int attenuation) {
-        this.attenuation = attenuation;
-    }
-
-    public short getFinetune() {
-        return finetune;
-    }
-
-    public void setFinetune(short finetune) {
-        this.finetune = finetune;
-    }
-
-    public List<DLSSampleLoop> getLoops() {
-        return loops;
-    }
-
-    public long getOptions() {
-        return options;
-    }
-
-    public void setOptions(long options) {
-        this.options = options;
-    }
-
-    public int getUnitynote() {
-        return unitynote;
-    }
-
-    public void setUnitynote(int unitynote) {
-        this.unitynote = unitynote;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class stores options how to playback sampled data like pitch/tuning,
+ * attenuation and loops.
+ * It is stored as a "wsmp" chunk inside DLS files.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSampleOptions {
+
+    protected int unitynote;
+    protected short finetune;
+    protected int attenuation;
+    protected long options;
+    protected List<DLSSampleLoop> loops = new ArrayList<DLSSampleLoop>();
+
+    public int getAttenuation() {
+        return attenuation;
+    }
+
+    public void setAttenuation(int attenuation) {
+        this.attenuation = attenuation;
+    }
+
+    public short getFinetune() {
+        return finetune;
+    }
+
+    public void setFinetune(short finetune) {
+        this.finetune = finetune;
+    }
+
+    public List<DLSSampleLoop> getLoops() {
+        return loops;
+    }
+
+    public long getOptions() {
+        return options;
+    }
+
+    public void setOptions(long options) {
+        this.options = options;
+    }
+
+    public int getUnitynote() {
+        return unitynote;
+    }
+
+    public void setUnitynote(int unitynote) {
+        this.unitynote = unitynote;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbank.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,1286 +1,1286 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import javax.sound.midi.Instrument;
-import javax.sound.midi.Patch;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.SoundbankResource;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.AudioFormat.Encoding;
-
-/**
- * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams).
- *
- * @author Karl Helgason
- */
-public class DLSSoundbank implements Soundbank {
-
-    static private class DLSID {
-        long i1;
-        int s1;
-        int s2;
-        int x1;
-        int x2;
-        int x3;
-        int x4;
-        int x5;
-        int x6;
-        int x7;
-        int x8;
-
-        private DLSID() {
-        }
-
-        public DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
-                int x5, int x6, int x7, int x8) {
-            this.i1 = i1;
-            this.s1 = s1;
-            this.s2 = s2;
-            this.x1 = x1;
-            this.x2 = x2;
-            this.x3 = x3;
-            this.x4 = x4;
-            this.x5 = x5;
-            this.x6 = x6;
-            this.x7 = x7;
-            this.x8 = x8;
-        }
-
-        public static DLSID read(RIFFReader riff) throws IOException {
-            DLSID d = new DLSID();
-            d.i1 = riff.readUnsignedInt();
-            d.s1 = riff.readUnsignedShort();
-            d.s2 = riff.readUnsignedShort();
-            d.x1 = riff.readByte();
-            d.x2 = riff.readByte();
-            d.x3 = riff.readByte();
-            d.x4 = riff.readByte();
-            d.x5 = riff.readByte();
-            d.x6 = riff.readByte();
-            d.x7 = riff.readByte();
-            d.x8 = riff.readByte();
-            return d;
-        }
-
-        public boolean equals(Object obj) {
-            if (!(obj instanceof DLSID)) {
-                return false;
-            }
-            DLSID t = (DLSID) obj;
-            return i1 == t.i1 && s1 == t.s1 && s2 == t.s2
-                && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4
-                && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8;
-        }
-    }
-
-    /** X = X & Y */
-    private static final int DLS_CDL_AND = 0x0001;
-    /** X = X | Y */
-    private static final int DLS_CDL_OR = 0x0002;
-    /** X = X ^ Y */
-    private static final int DLS_CDL_XOR = 0x0003;
-    /** X = X + Y */
-    private static final int DLS_CDL_ADD = 0x0004;
-    /** X = X - Y */
-    private static final int DLS_CDL_SUBTRACT = 0x0005;
-    /** X = X * Y */
-    private static final int DLS_CDL_MULTIPLY = 0x0006;
-    /** X = X / Y */
-    private static final int DLS_CDL_DIVIDE = 0x0007;
-    /** X = X && Y */
-    private static final int DLS_CDL_LOGICAL_AND = 0x0008;
-    /** X = X || Y */
-    private static final int DLS_CDL_LOGICAL_OR = 0x0009;
-    /** X = (X < Y) */
-    private static final int DLS_CDL_LT = 0x000A;
-    /** X = (X <= Y) */
-    private static final int DLS_CDL_LE = 0x000B;
-    /** X = (X > Y) */
-    private static final int DLS_CDL_GT = 0x000C;
-    /** X = (X >= Y) */
-    private static final int DLS_CDL_GE = 0x000D;
-    /** X = (X == Y) */
-    private static final int DLS_CDL_EQ = 0x000E;
-    /** X = !X */
-    private static final int DLS_CDL_NOT = 0x000F;
-    /** 32-bit constant */
-    private static final int DLS_CDL_CONST = 0x0010;
-    /** 32-bit value returned from query */
-    private static final int DLS_CDL_QUERY = 0x0011;
-    /** 32-bit value returned from query */
-    private static final int DLS_CDL_QUERYSUPPORTED = 0x0012;
-
-    private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24,
-            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-    private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25,
-            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-    private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26,
-            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-    private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27,
-            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-    private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5,
-            0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
-    private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28,
-            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
-    private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181,
-            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
-    private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182,
-            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
-    private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713,
-            0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
-
-    private long major = -1;
-    private long minor = -1;
-
-    private DLSInfo info = new DLSInfo();
-
-    private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>();
-    private List<DLSSample> samples = new ArrayList<DLSSample>();
-
-    private boolean largeFormat = false;
-    private File sampleFile;
-
-    public DLSSoundbank() {
-    }
-
-    public DLSSoundbank(URL url) throws IOException {
-        InputStream is = url.openStream();
-        try {
-            readSoundbank(is);
-        } finally {
-            is.close();
-        }
-    }
-
-    public DLSSoundbank(File file) throws IOException {
-        largeFormat = true;
-        sampleFile = file;
-        InputStream is = new FileInputStream(file);
-        try {
-            readSoundbank(is);
-        } finally {
-            is.close();
-        }
-    }
-
-    public DLSSoundbank(InputStream inputstream) throws IOException {
-        readSoundbank(inputstream);
-    }
-
-    private void readSoundbank(InputStream inputstream) throws IOException {
-        RIFFReader riff = new RIFFReader(inputstream);
-        if (!riff.getFormat().equals("RIFF")) {
-            throw new RIFFInvalidFormatException(
-                    "Input stream is not a valid RIFF stream!");
-        }
-        if (!riff.getType().equals("DLS ")) {
-            throw new RIFFInvalidFormatException(
-                    "Input stream is not a valid DLS soundbank!");
-        }
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            if (chunk.getFormat().equals("LIST")) {
-                if (chunk.getType().equals("INFO"))
-                    readInfoChunk(chunk);
-                if (chunk.getType().equals("lins"))
-                    readLinsChunk(chunk);
-                if (chunk.getType().equals("wvpl"))
-                    readWvplChunk(chunk);
-            } else {
-                if (chunk.getFormat().equals("cdl ")) {
-                    if (!readCdlChunk(chunk)) {
-                        throw new RIFFInvalidFormatException(
-                                "DLS file isn't supported!");
-                    }
-                }
-                if (chunk.getFormat().equals("colh")) {
-                    // skipped because we will load the entire bank into memory
-                    // long instrumentcount = chunk.readUnsignedInt();
-                    // System.out.println("instrumentcount = "+ instrumentcount);
-                }
-                if (chunk.getFormat().equals("ptbl")) {
-                    // Pool Table Chunk
-                    // skipped because we will load the entire bank into memory
-                }
-                if (chunk.getFormat().equals("vers")) {
-                    major = chunk.readUnsignedInt();
-                    minor = chunk.readUnsignedInt();
-                }
-            }
-        }
-
-        for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) {
-            entry.getKey().sample = samples.get((int)entry.getValue().longValue());
-        }
-
-        temp_rgnassign = null;
-    }
-
-    private boolean cdlIsQuerySupported(DLSID uuid) {
-        return uuid.equals(DLSID_GMInHardware)
-            || uuid.equals(DLSID_GSInHardware)
-            || uuid.equals(DLSID_XGInHardware)
-            || uuid.equals(DLSID_SupportsDLS1)
-            || uuid.equals(DLSID_SupportsDLS2)
-            || uuid.equals(DLSID_SampleMemorySize)
-            || uuid.equals(DLSID_ManufacturersID)
-            || uuid.equals(DLSID_ProductID)
-            || uuid.equals(DLSID_SamplePlaybackRate);
-    }
-
-    private long cdlQuery(DLSID uuid) {
-        if (uuid.equals(DLSID_GMInHardware))
-            return 1;
-        if (uuid.equals(DLSID_GSInHardware))
-            return 0;
-        if (uuid.equals(DLSID_XGInHardware))
-            return 0;
-        if (uuid.equals(DLSID_SupportsDLS1))
-            return 1;
-        if (uuid.equals(DLSID_SupportsDLS2))
-            return 1;
-        if (uuid.equals(DLSID_SampleMemorySize))
-            return Runtime.getRuntime().totalMemory();
-        if (uuid.equals(DLSID_ManufacturersID))
-            return 0;
-        if (uuid.equals(DLSID_ProductID))
-            return 0;
-        if (uuid.equals(DLSID_SamplePlaybackRate))
-            return 44100;
-        return 0;
-    }
-
-
-    // Reading cdl-ck Chunk
-    // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2
-    private boolean readCdlChunk(RIFFReader riff) throws IOException {
-
-        DLSID uuid;
-        long x;
-        long y;
-        Stack<Long> stack = new Stack<Long>();
-
-        while (riff.available() != 0) {
-            int opcode = riff.readUnsignedShort();
-            switch (opcode) {
-            case DLS_CDL_AND:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(((x != 0) & (y != 0)) ? 1 : 0));
-                break;
-            case DLS_CDL_OR:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(((x != 0) | (y != 0)) ? 1 : 0));
-                break;
-            case DLS_CDL_XOR:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(((x != 0) ^ (y != 0)) ? 1 : 0));
-                break;
-            case DLS_CDL_ADD:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(x + y));
-                break;
-            case DLS_CDL_SUBTRACT:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(x - y));
-                break;
-            case DLS_CDL_MULTIPLY:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(x * y));
-                break;
-            case DLS_CDL_DIVIDE:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(x / y));
-                break;
-            case DLS_CDL_LOGICAL_AND:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(((x != 0) & (y != 0)) ? 1 : 0));
-                break;
-            case DLS_CDL_LOGICAL_OR:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long(((x != 0) | (y != 0)) ? 1 : 0));
-                break;
-            case DLS_CDL_LT:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long((x < y) ? 1 : 0));
-                break;
-            case DLS_CDL_LE:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long((x <= y) ? 1 : 0));
-                break;
-            case DLS_CDL_GT:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long((x > y) ? 1 : 0));
-                break;
-            case DLS_CDL_GE:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long((x >= y) ? 1 : 0));
-                break;
-            case DLS_CDL_EQ:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long((x == y) ? 1 : 0));
-                break;
-            case DLS_CDL_NOT:
-                x = stack.pop();
-                y = stack.pop();
-                stack.push(new Long((x == 0) ? 1 : 0));
-                break;
-            case DLS_CDL_CONST:
-                stack.push(new Long(riff.readUnsignedInt()));
-                break;
-            case DLS_CDL_QUERY:
-                uuid = DLSID.read(riff);
-                stack.push(cdlQuery(uuid));
-                break;
-            case DLS_CDL_QUERYSUPPORTED:
-                uuid = DLSID.read(riff);
-                stack.push(new Long(cdlIsQuerySupported(uuid) ? 1 : 0));
-                break;
-            default:
-                break;
-            }
-        }
-        if (stack.isEmpty())
-            return false;
-
-        return stack.pop() == 1;
-    }
-
-    private void readInfoChunk(RIFFReader riff) throws IOException {
-        info.name = null;
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("INAM"))
-                info.name = chunk.readString(chunk.available());
-            else if (format.equals("ICRD"))
-                info.creationDate = chunk.readString(chunk.available());
-            else if (format.equals("IENG"))
-                info.engineers = chunk.readString(chunk.available());
-            else if (format.equals("IPRD"))
-                info.product = chunk.readString(chunk.available());
-            else if (format.equals("ICOP"))
-                info.copyright = chunk.readString(chunk.available());
-            else if (format.equals("ICMT"))
-                info.comments = chunk.readString(chunk.available());
-            else if (format.equals("ISFT"))
-                info.tools = chunk.readString(chunk.available());
-            else if (format.equals("IARL"))
-                info.archival_location = chunk.readString(chunk.available());
-            else if (format.equals("IART"))
-                info.artist = chunk.readString(chunk.available());
-            else if (format.equals("ICMS"))
-                info.commissioned = chunk.readString(chunk.available());
-            else if (format.equals("IGNR"))
-                info.genre = chunk.readString(chunk.available());
-            else if (format.equals("IKEY"))
-                info.keywords = chunk.readString(chunk.available());
-            else if (format.equals("IMED"))
-                info.medium = chunk.readString(chunk.available());
-            else if (format.equals("ISBJ"))
-                info.subject = chunk.readString(chunk.available());
-            else if (format.equals("ISRC"))
-                info.source = chunk.readString(chunk.available());
-            else if (format.equals("ISRF"))
-                info.source_form = chunk.readString(chunk.available());
-            else if (format.equals("ITCH"))
-                info.technician = chunk.readString(chunk.available());
-        }
-    }
-
-    private void readLinsChunk(RIFFReader riff) throws IOException {
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            if (chunk.getFormat().equals("LIST")) {
-                if (chunk.getType().equals("ins "))
-                    readInsChunk(chunk);
-            }
-        }
-    }
-
-    private void readInsChunk(RIFFReader riff) throws IOException {
-        DLSInstrument instrument = new DLSInstrument(this);
-
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("LIST")) {
-                if (chunk.getType().equals("INFO")) {
-                    readInsInfoChunk(instrument, chunk);
-                }
-                if (chunk.getType().equals("lrgn")) {
-                    while (chunk.hasNextChunk()) {
-                        RIFFReader subchunk = chunk.nextChunk();
-                        if (subchunk.getFormat().equals("LIST")) {
-                            if (subchunk.getType().equals("rgn ")) {
-                                DLSRegion split = new DLSRegion();
-                                if (readRgnChunk(split, subchunk))
-                                    instrument.getRegions().add(split);
-                            }
-                            if (subchunk.getType().equals("rgn2")) {
-                                // support for DLS level 2 regions
-                                DLSRegion split = new DLSRegion();
-                                if (readRgnChunk(split, subchunk))
-                                    instrument.getRegions().add(split);
-                            }
-                        }
-                    }
-                }
-                if (chunk.getType().equals("lart")) {
-                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
-                    while (chunk.hasNextChunk()) {
-                        RIFFReader subchunk = chunk.nextChunk();
-                        if (chunk.getFormat().equals("cdl ")) {
-                            if (!readCdlChunk(chunk)) {
-                                modlist.clear();
-                                break;
-                            }
-                        }
-                        if (subchunk.getFormat().equals("art1"))
-                            readArt1Chunk(modlist, subchunk);
-                    }
-                    instrument.getModulators().addAll(modlist);
-                }
-                if (chunk.getType().equals("lar2")) {
-                    // support for DLS level 2 ART
-                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
-                    while (chunk.hasNextChunk()) {
-                        RIFFReader subchunk = chunk.nextChunk();
-                        if (chunk.getFormat().equals("cdl ")) {
-                            if (!readCdlChunk(chunk)) {
-                                modlist.clear();
-                                break;
-                            }
-                        }
-                        if (subchunk.getFormat().equals("art2"))
-                            readArt2Chunk(modlist, subchunk);
-                    }
-                    instrument.getModulators().addAll(modlist);
-                }
-            } else {
-                if (format.equals("dlid")) {
-                    instrument.guid = new byte[16];
-                    chunk.read(instrument.guid);
-                }
-                if (format.equals("insh")) {
-                    chunk.readUnsignedInt(); // Read Region Count - ignored
-
-                    int bank = chunk.read();             // LSB
-                    bank += (chunk.read() & 127) << 7;   // MSB
-                    chunk.read(); // Read Reserved byte
-                    int drumins = chunk.read();          // Drum Instrument
-
-                    int id = chunk.read() & 127; // Read only first 7 bits
-                    chunk.read(); // Read Reserved byte
-                    chunk.read(); // Read Reserved byte
-                    chunk.read(); // Read Reserved byte
-
-                    instrument.bank = bank;
-                    instrument.preset = (int) id;
-                    instrument.druminstrument = (drumins & 128) > 0;
-                    //System.out.println("bank="+bank+" drumkit="+drumkit
-                    //        +" id="+id);
-                }
-
-            }
-        }
-        instruments.add(instrument);
-    }
-
-    private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff)
-            throws IOException {
-        long size = riff.readUnsignedInt();
-        long count = riff.readUnsignedInt();
-
-        if (size - 8 != 0)
-            riff.skip(size - 8);
-
-        for (int i = 0; i < count; i++) {
-            DLSModulator modulator = new DLSModulator();
-            modulator.version = 1;
-            modulator.source = riff.readUnsignedShort();
-            modulator.control = riff.readUnsignedShort();
-            modulator.destination = riff.readUnsignedShort();
-            modulator.transform = riff.readUnsignedShort();
-            modulator.scale = riff.readInt();
-            modulators.add(modulator);
-        }
-    }
-
-    private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff)
-            throws IOException {
-        long size = riff.readUnsignedInt();
-        long count = riff.readUnsignedInt();
-
-        if (size - 8 != 0)
-            riff.skip(size - 8);
-
-        for (int i = 0; i < count; i++) {
-            DLSModulator modulator = new DLSModulator();
-            modulator.version = 2;
-            modulator.source = riff.readUnsignedShort();
-            modulator.control = riff.readUnsignedShort();
-            modulator.destination = riff.readUnsignedShort();
-            modulator.transform = riff.readUnsignedShort();
-            modulator.scale = riff.readInt();
-            modulators.add(modulator);
-        }
-    }
-
-    private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>();
-
-    private boolean readRgnChunk(DLSRegion split, RIFFReader riff)
-            throws IOException {
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("LIST")) {
-                if (chunk.getType().equals("lart")) {
-                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
-                    while (chunk.hasNextChunk()) {
-                        RIFFReader subchunk = chunk.nextChunk();
-                        if (chunk.getFormat().equals("cdl ")) {
-                            if (!readCdlChunk(chunk)) {
-                                modlist.clear();
-                                break;
-                            }
-                        }
-                        if (subchunk.getFormat().equals("art1"))
-                            readArt1Chunk(modlist, subchunk);
-                    }
-                    split.getModulators().addAll(modlist);
-                }
-                if (chunk.getType().equals("lar2")) {
-                    // support for DLS level 2 ART
-                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
-                    while (chunk.hasNextChunk()) {
-                        RIFFReader subchunk = chunk.nextChunk();
-                        if (chunk.getFormat().equals("cdl ")) {
-                            if (!readCdlChunk(chunk)) {
-                                modlist.clear();
-                                break;
-                            }
-                        }
-                        if (subchunk.getFormat().equals("art2"))
-                            readArt2Chunk(modlist, subchunk);
-                    }
-                    split.getModulators().addAll(modlist);
-                }
-            } else {
-
-                if (format.equals("cdl ")) {
-                    if (!readCdlChunk(chunk))
-                        return false;
-                }
-                if (format.equals("rgnh")) {
-                    split.keyfrom = chunk.readUnsignedShort();
-                    split.keyto = chunk.readUnsignedShort();
-                    split.velfrom = chunk.readUnsignedShort();
-                    split.velto = chunk.readUnsignedShort();
-                    split.options = chunk.readUnsignedShort();
-                    split.exclusiveClass = chunk.readUnsignedShort();
-                }
-                if (format.equals("wlnk")) {
-                    split.fusoptions = chunk.readUnsignedShort();
-                    split.phasegroup = chunk.readUnsignedShort();
-                    split.channel = chunk.readUnsignedInt();
-                    long sampleid = chunk.readUnsignedInt();
-                    temp_rgnassign.put(split, sampleid);
-                }
-                if (format.equals("wsmp")) {
-                    split.sampleoptions = new DLSSampleOptions();
-                    readWsmpChunk(split.sampleoptions, chunk);
-                }
-            }
-        }
-        return true;
-    }
-
-    private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff)
-            throws IOException {
-        long size = riff.readUnsignedInt();
-        sampleOptions.unitynote = riff.readUnsignedShort();
-        sampleOptions.finetune = riff.readShort();
-        sampleOptions.attenuation = riff.readInt();
-        sampleOptions.options = riff.readUnsignedInt();
-        long loops = riff.readInt();
-
-        if (size > 20)
-            riff.skip(size - 20);
-
-        for (int i = 0; i < loops; i++) {
-            DLSSampleLoop loop = new DLSSampleLoop();
-            long size2 = riff.readUnsignedInt();
-            loop.type = riff.readUnsignedInt();
-            loop.start = riff.readUnsignedInt();
-            loop.length = riff.readUnsignedInt();
-            sampleOptions.loops.add(loop);
-            if (size2 > 16)
-                riff.skip(size2 - 16);
-        }
-    }
-
-    private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff)
-            throws IOException {
-        dlsinstrument.info.name = null;
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("INAM")) {
-                dlsinstrument.info.name = chunk.readString(chunk.available());
-            } else if (format.equals("ICRD")) {
-                dlsinstrument.info.creationDate =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IENG")) {
-                dlsinstrument.info.engineers =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IPRD")) {
-                dlsinstrument.info.product = chunk.readString(chunk.available());
-            } else if (format.equals("ICOP")) {
-                dlsinstrument.info.copyright =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("ICMT")) {
-                dlsinstrument.info.comments =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("ISFT")) {
-                dlsinstrument.info.tools = chunk.readString(chunk.available());
-            } else if (format.equals("IARL")) {
-                dlsinstrument.info.archival_location =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IART")) {
-                dlsinstrument.info.artist = chunk.readString(chunk.available());
-            } else if (format.equals("ICMS")) {
-                dlsinstrument.info.commissioned =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IGNR")) {
-                dlsinstrument.info.genre = chunk.readString(chunk.available());
-            } else if (format.equals("IKEY")) {
-                dlsinstrument.info.keywords =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IMED")) {
-                dlsinstrument.info.medium = chunk.readString(chunk.available());
-            } else if (format.equals("ISBJ")) {
-                dlsinstrument.info.subject = chunk.readString(chunk.available());
-            } else if (format.equals("ISRC")) {
-                dlsinstrument.info.source = chunk.readString(chunk.available());
-            } else if (format.equals("ISRF")) {
-                dlsinstrument.info.source_form =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("ITCH")) {
-                dlsinstrument.info.technician =
-                        chunk.readString(chunk.available());
-            }
-        }
-    }
-
-    private void readWvplChunk(RIFFReader riff) throws IOException {
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            if (chunk.getFormat().equals("LIST")) {
-                if (chunk.getType().equals("wave"))
-                    readWaveChunk(chunk);
-            }
-        }
-    }
-
-    private void readWaveChunk(RIFFReader riff) throws IOException {
-        DLSSample sample = new DLSSample(this);
-
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("LIST")) {
-                if (chunk.getType().equals("INFO")) {
-                    readWaveInfoChunk(sample, chunk);
-                }
-            } else {
-                if (format.equals("dlid")) {
-                    sample.guid = new byte[16];
-                    chunk.read(sample.guid);
-                }
-
-                if (format.equals("fmt ")) {
-                    int sampleformat = chunk.readUnsignedShort();
-                    if (sampleformat != 1 && sampleformat != 3) {
-                        throw new RIFFInvalidDataException(
-                                "Only PCM samples are supported!");
-                    }
-                    int channels = chunk.readUnsignedShort();
-                    long samplerate = chunk.readUnsignedInt();
-                    // bytes per sec
-                    /* long framerate = */ chunk.readUnsignedInt();
-                    // block align, framesize
-                    int framesize = chunk.readUnsignedShort();
-                    int bits = chunk.readUnsignedShort();
-                    AudioFormat audioformat = null;
-                    if (sampleformat == 1) {
-                        if (bits == 8) {
-                            audioformat = new AudioFormat(
-                                    Encoding.PCM_UNSIGNED, samplerate, bits,
-                                    channels, framesize, samplerate, false);
-                        } else {
-                            audioformat = new AudioFormat(
-                                    Encoding.PCM_SIGNED, samplerate, bits,
-                                    channels, framesize, samplerate, false);
-                        }
-                    }
-                    if (sampleformat == 3) {
-                        audioformat = new AudioFormat(
-                                AudioFloatConverter.PCM_FLOAT, samplerate, bits,
-                                channels, framesize, samplerate, false);
-                    }
-
-                    sample.format = audioformat;
-                }
-
-                if (format.equals("data")) {
-                    if (largeFormat) {
-                        sample.setData(new ModelByteBuffer(sampleFile,
-                                chunk.getFilePointer(), chunk.available()));
-                    } else {
-                        byte[] buffer = new byte[chunk.available()];
-                        //	chunk.read(buffer);
-                        sample.setData(buffer);
-
-                        int read = 0;
-                        int avail = chunk.available();
-                        while (read != avail) {
-                            if (avail - read > 65536) {
-                                chunk.read(buffer, read, 65536);
-                                read += 65536;
-                            } else {
-                                chunk.read(buffer, read, avail - read);
-                                read = avail;
-                            }
-                        }
-                    }
-                }
-
-                if (format.equals("wsmp")) {
-                    sample.sampleoptions = new DLSSampleOptions();
-                    readWsmpChunk(sample.sampleoptions, chunk);
-                }
-            }
-        }
-
-        samples.add(sample);
-
-    }
-
-    private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff)
-            throws IOException {
-        dlssample.info.name = null;
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("INAM")) {
-                dlssample.info.name = chunk.readString(chunk.available());
-            } else if (format.equals("ICRD")) {
-                dlssample.info.creationDate =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IENG")) {
-                dlssample.info.engineers = chunk.readString(chunk.available());
-            } else if (format.equals("IPRD")) {
-                dlssample.info.product = chunk.readString(chunk.available());
-            } else if (format.equals("ICOP")) {
-                dlssample.info.copyright = chunk.readString(chunk.available());
-            } else if (format.equals("ICMT")) {
-                dlssample.info.comments = chunk.readString(chunk.available());
-            } else if (format.equals("ISFT")) {
-                dlssample.info.tools = chunk.readString(chunk.available());
-            } else if (format.equals("IARL")) {
-                dlssample.info.archival_location =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IART")) {
-                dlssample.info.artist = chunk.readString(chunk.available());
-            } else if (format.equals("ICMS")) {
-                dlssample.info.commissioned =
-                        chunk.readString(chunk.available());
-            } else if (format.equals("IGNR")) {
-                dlssample.info.genre = chunk.readString(chunk.available());
-            } else if (format.equals("IKEY")) {
-                dlssample.info.keywords = chunk.readString(chunk.available());
-            } else if (format.equals("IMED")) {
-                dlssample.info.medium = chunk.readString(chunk.available());
-            } else if (format.equals("ISBJ")) {
-                dlssample.info.subject = chunk.readString(chunk.available());
-            } else if (format.equals("ISRC")) {
-                dlssample.info.source = chunk.readString(chunk.available());
-            } else if (format.equals("ISRF")) {
-                dlssample.info.source_form = chunk.readString(chunk.available());
-            } else if (format.equals("ITCH")) {
-                dlssample.info.technician = chunk.readString(chunk.available());
-            }
-        }
-    }
-
-    public void save(String name) throws IOException {
-        writeSoundbank(new RIFFWriter(name, "DLS "));
-    }
-
-    public void save(File file) throws IOException {
-        writeSoundbank(new RIFFWriter(file, "DLS "));
-    }
-
-    public void save(OutputStream out) throws IOException {
-        writeSoundbank(new RIFFWriter(out, "DLS "));
-    }
-
-    private void writeSoundbank(RIFFWriter writer) throws IOException {
-        RIFFWriter colh_chunk = writer.writeChunk("colh");
-        colh_chunk.writeUnsignedInt(instruments.size());
-
-        if (major != -1 && minor != -1) {
-            RIFFWriter vers_chunk = writer.writeChunk("vers");
-            vers_chunk.writeUnsignedInt(major);
-            vers_chunk.writeUnsignedInt(minor);
-        }
-
-        writeInstruments(writer.writeList("lins"));
-
-        RIFFWriter ptbl = writer.writeChunk("ptbl");
-        ptbl.writeUnsignedInt(8);
-        ptbl.writeUnsignedInt(samples.size());
-        long ptbl_offset = writer.getFilePointer();
-        for (int i = 0; i < samples.size(); i++)
-            ptbl.writeUnsignedInt(0);
-
-        RIFFWriter wvpl = writer.writeList("wvpl");
-        long off = wvpl.getFilePointer();
-        List<Long> offsettable = new ArrayList<Long>();
-        for (DLSSample sample : samples) {
-            offsettable.add(new Long(wvpl.getFilePointer() - off));
-            writeSample(wvpl.writeList("wave"), sample);
-        }
-
-        // small cheat, we are going to rewrite data back in wvpl
-        long bak = writer.getFilePointer();
-        writer.seek(ptbl_offset);
-        writer.setWriteOverride(true);
-        for (Long offset : offsettable)
-            writer.writeUnsignedInt(offset.longValue());
-        writer.setWriteOverride(false);
-        writer.seek(bak);
-
-        writeInfo(writer.writeList("INFO"), info);
-
-        writer.close();
-    }
-
-    private void writeSample(RIFFWriter writer, DLSSample sample)
-            throws IOException {
-
-        AudioFormat audioformat = sample.getFormat();
-
-        Encoding encoding = audioformat.getEncoding();
-        float sampleRate = audioformat.getSampleRate();
-        int sampleSizeInBits = audioformat.getSampleSizeInBits();
-        int channels = audioformat.getChannels();
-        int frameSize = audioformat.getFrameSize();
-        float frameRate = audioformat.getFrameRate();
-        boolean bigEndian = audioformat.isBigEndian();
-
-        boolean convert_needed = false;
-
-        if (audioformat.getSampleSizeInBits() == 8) {
-            if (!encoding.equals(Encoding.PCM_UNSIGNED)) {
-                encoding = Encoding.PCM_UNSIGNED;
-                convert_needed = true;
-            }
-        } else {
-            if (!encoding.equals(Encoding.PCM_SIGNED)) {
-                encoding = Encoding.PCM_SIGNED;
-                convert_needed = true;
-            }
-            if (bigEndian) {
-                bigEndian = false;
-                convert_needed = true;
-            }
-        }
-
-        if (convert_needed) {
-            audioformat = new AudioFormat(encoding, sampleRate,
-                    sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
-        }
-
-        // fmt
-        RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
-        int sampleformat = 0;
-        if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED))
-            sampleformat = 1;
-        else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
-            sampleformat = 1;
-        else if (audioformat.getEncoding().equals(AudioFloatConverter.PCM_FLOAT))
-            sampleformat = 3;
-
-        fmt_chunk.writeUnsignedShort(sampleformat);
-        fmt_chunk.writeUnsignedShort(audioformat.getChannels());
-        fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate());
-        long srate = (long)audioformat.getSampleRate();
-        srate *= audioformat.getChannels();
-        srate *= audioformat.getSampleSizeInBits() / 8;
-        //fmt_chunk.writeUnsignedInt((long)audioformat.getFrameRate());
-        fmt_chunk.writeUnsignedInt(srate);
-        fmt_chunk.writeUnsignedShort(audioformat.getFrameSize());
-        fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits());
-        fmt_chunk.write(0);
-        fmt_chunk.write(0);
-
-        writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions);
-
-        if (convert_needed) {
-            RIFFWriter data_chunk = writer.writeChunk("data");
-            AudioInputStream stream = AudioSystem.getAudioInputStream(
-                    audioformat, (AudioInputStream)sample.getData());
-            byte[] buff = new byte[1024];
-            int ret;
-            while ((ret = stream.read(buff)) != -1) {
-                data_chunk.write(buff, 0, ret);
-            }
-        } else {
-            RIFFWriter data_chunk = writer.writeChunk("data");
-            ModelByteBuffer databuff = sample.getDataBuffer();
-            databuff.writeTo(data_chunk);
-            /*
-            data_chunk.write(databuff.array(),
-            databuff.arrayOffset(),
-            databuff.capacity());
-             */
-        }
-
-        writeInfo(writer.writeList("INFO"), sample.info);
-    }
-
-    private void writeInstruments(RIFFWriter writer) throws IOException {
-        for (DLSInstrument instrument : instruments) {
-            writeInstrument(writer.writeList("ins "), instrument);
-        }
-    }
-
-    private void writeInstrument(RIFFWriter writer, DLSInstrument instrument)
-            throws IOException {
-
-        int art1_count = 0;
-        int art2_count = 0;
-        for (DLSModulator modulator : instrument.getModulators()) {
-            if (modulator.version == 1)
-                art1_count++;
-            if (modulator.version == 2)
-                art2_count++;
-        }
-        for (DLSRegion region : instrument.regions) {
-            for (DLSModulator modulator : region.getModulators()) {
-                if (modulator.version == 1)
-                    art1_count++;
-                if (modulator.version == 2)
-                    art2_count++;
-            }
-        }
-
-        int version = 1;
-        if (art2_count > 0)
-            version = 2;
-
-        RIFFWriter insh_chunk = writer.writeChunk("insh");
-        insh_chunk.writeUnsignedInt(instrument.getRegions().size());
-        insh_chunk.writeUnsignedInt(instrument.bank +
-                (instrument.druminstrument ? 2147483648L : 0));
-        insh_chunk.writeUnsignedInt(instrument.preset);
-
-        RIFFWriter lrgn = writer.writeList("lrgn");
-        for (DLSRegion region: instrument.regions)
-            writeRegion(lrgn, region, version);
-
-        writeArticulators(writer, instrument.getModulators());
-
-        writeInfo(writer.writeList("INFO"), instrument.info);
-
-    }
-
-    private void writeArticulators(RIFFWriter writer,
-            List<DLSModulator> modulators) throws IOException {
-        int art1_count = 0;
-        int art2_count = 0;
-        for (DLSModulator modulator : modulators) {
-            if (modulator.version == 1)
-                art1_count++;
-            if (modulator.version == 2)
-                art2_count++;
-        }
-        if (art1_count > 0) {
-            RIFFWriter lar1 = writer.writeList("lart");
-            RIFFWriter art1 = lar1.writeChunk("art1");
-            art1.writeUnsignedInt(8);
-            art1.writeUnsignedInt(art1_count);
-            for (DLSModulator modulator : modulators) {
-                if (modulator.version == 1) {
-                    art1.writeUnsignedShort(modulator.source);
-                    art1.writeUnsignedShort(modulator.control);
-                    art1.writeUnsignedShort(modulator.destination);
-                    art1.writeUnsignedShort(modulator.transform);
-                    art1.writeInt(modulator.scale);
-                }
-            }
-        }
-        if (art2_count > 0) {
-            RIFFWriter lar2 = writer.writeList("lar2");
-            RIFFWriter art2 = lar2.writeChunk("art2");
-            art2.writeUnsignedInt(8);
-            art2.writeUnsignedInt(art2_count);
-            for (DLSModulator modulator : modulators) {
-                if (modulator.version == 2) {
-                    art2.writeUnsignedShort(modulator.source);
-                    art2.writeUnsignedShort(modulator.control);
-                    art2.writeUnsignedShort(modulator.destination);
-                    art2.writeUnsignedShort(modulator.transform);
-                    art2.writeInt(modulator.scale);
-                }
-            }
-        }
-    }
-
-    private void writeRegion(RIFFWriter writer, DLSRegion region, int version)
-            throws IOException {
-        RIFFWriter rgns = null;
-        if (version == 1)
-            rgns = writer.writeList("rgn ");
-        if (version == 2)
-            rgns = writer.writeList("rgn2");
-        if (rgns == null)
-            return;
-
-        RIFFWriter rgnh = rgns.writeChunk("rgnh");
-        rgnh.writeUnsignedShort(region.keyfrom);
-        rgnh.writeUnsignedShort(region.keyto);
-        rgnh.writeUnsignedShort(region.velfrom);
-        rgnh.writeUnsignedShort(region.velto);
-        rgnh.writeUnsignedShort(region.options);
-        rgnh.writeUnsignedShort(region.exclusiveClass);
-
-        if (region.sampleoptions != null)
-            writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions);
-
-        if (region.sample != null) {
-            if (samples.indexOf(region.sample) != -1) {
-                RIFFWriter wlnk = rgns.writeChunk("wlnk");
-                wlnk.writeUnsignedShort(region.fusoptions);
-                wlnk.writeUnsignedShort(region.phasegroup);
-                wlnk.writeUnsignedInt(region.channel);
-                wlnk.writeUnsignedInt(samples.indexOf(region.sample));
-            }
-        }
-        writeArticulators(rgns, region.getModulators());
-        rgns.close();
-    }
-
-    private void writeSampleOptions(RIFFWriter wsmp,
-            DLSSampleOptions sampleoptions) throws IOException {
-        wsmp.writeUnsignedInt(20);
-        wsmp.writeUnsignedShort(sampleoptions.unitynote);
-        wsmp.writeShort(sampleoptions.finetune);
-        wsmp.writeInt(sampleoptions.attenuation);
-        wsmp.writeUnsignedInt(sampleoptions.options);
-        wsmp.writeInt(sampleoptions.loops.size());
-
-        for (DLSSampleLoop loop : sampleoptions.loops) {
-            wsmp.writeUnsignedInt(16);
-            wsmp.writeUnsignedInt(loop.type);
-            wsmp.writeUnsignedInt(loop.start);
-            wsmp.writeUnsignedInt(loop.length);
-        }
-    }
-
-    private void writeInfoStringChunk(RIFFWriter writer,
-            String name, String value) throws IOException {
-        if (value == null)
-            return;
-        RIFFWriter chunk = writer.writeChunk(name);
-        chunk.writeString(value);
-        int len = value.getBytes("ascii").length;
-        chunk.write(0);
-        len++;
-        if (len % 2 != 0)
-            chunk.write(0);
-    }
-
-    private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException {
-        writeInfoStringChunk(writer, "INAM", info.name);
-        writeInfoStringChunk(writer, "ICRD", info.creationDate);
-        writeInfoStringChunk(writer, "IENG", info.engineers);
-        writeInfoStringChunk(writer, "IPRD", info.product);
-        writeInfoStringChunk(writer, "ICOP", info.copyright);
-        writeInfoStringChunk(writer, "ICMT", info.comments);
-        writeInfoStringChunk(writer, "ISFT", info.tools);
-        writeInfoStringChunk(writer, "IARL", info.archival_location);
-        writeInfoStringChunk(writer, "IART", info.artist);
-        writeInfoStringChunk(writer, "ICMS", info.commissioned);
-        writeInfoStringChunk(writer, "IGNR", info.genre);
-        writeInfoStringChunk(writer, "IKEY", info.keywords);
-        writeInfoStringChunk(writer, "IMED", info.medium);
-        writeInfoStringChunk(writer, "ISBJ", info.subject);
-        writeInfoStringChunk(writer, "ISRC", info.source);
-        writeInfoStringChunk(writer, "ISRF", info.source_form);
-        writeInfoStringChunk(writer, "ITCH", info.technician);
-    }
-
-    public DLSInfo getInfo() {
-        return info;
-    }
-
-    public String getName() {
-        return info.name;
-    }
-
-    public String getVersion() {
-        return major + "." + minor;
-    }
-
-    public String getVendor() {
-        return info.engineers;
-    }
-
-    public String getDescription() {
-        return info.comments;
-    }
-
-    public void setName(String s) {
-        info.name = s;
-    }
-
-    public void setVendor(String s) {
-        info.engineers = s;
-    }
-
-    public void setDescription(String s) {
-        info.comments = s;
-    }
-
-    public SoundbankResource[] getResources() {
-        SoundbankResource[] resources = new SoundbankResource[samples.size()];
-        int j = 0;
-        for (int i = 0; i < samples.size(); i++)
-            resources[j++] = samples.get(i);
-        return resources;
-    }
-
-    public DLSInstrument[] getInstruments() {
-        DLSInstrument[] inslist_array =
-                instruments.toArray(new DLSInstrument[instruments.size()]);
-        Arrays.sort(inslist_array, new ModelInstrumentComparator());
-        return inslist_array;
-    }
-
-    public DLSSample[] getSamples() {
-        return samples.toArray(new DLSSample[samples.size()]);
-    }
-
-    public Instrument getInstrument(Patch patch) {
-        int program = patch.getProgram();
-        int bank = patch.getBank();
-        boolean percussion = false;
-        if (patch instanceof ModelPatch)
-            percussion = ((ModelPatch) patch).isPercussion();
-        for (Instrument instrument : instruments) {
-            Patch patch2 = instrument.getPatch();
-            int program2 = patch2.getProgram();
-            int bank2 = patch2.getBank();
-            if (program == program2 && bank == bank2) {
-                boolean percussion2 = false;
-                if (patch2 instanceof ModelPatch)
-                    percussion2 = ((ModelPatch) patch2).isPercussion();
-                if (percussion == percussion2)
-                    return instrument;
-            }
-        }
-        return null;
-    }
-
-    public void addResource(SoundbankResource resource) {
-        if (resource instanceof DLSInstrument)
-            instruments.add((DLSInstrument) resource);
-        if (resource instanceof DLSSample)
-            samples.add((DLSSample) resource);
-    }
-
-    public void removeResource(SoundbankResource resource) {
-        if (resource instanceof DLSInstrument)
-            instruments.remove((DLSInstrument) resource);
-        if (resource instanceof DLSSample)
-            samples.remove((DLSSample) resource);
-    }
-
-    public void addInstrument(DLSInstrument resource) {
-        instruments.add(resource);
-    }
-
-    public void removeInstrument(DLSInstrument resource) {
-        instruments.remove(resource);
-    }
-
-    public long getMajor() {
-        return major;
-    }
-
-    public void setMajor(long major) {
-        this.major = major;
-    }
-
-    public long getMinor() {
-        return minor;
-    }
-
-    public void setMinor(long minor) {
-        this.minor = minor;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Stack;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * A DLS Level 1 and Level 2 soundbank reader (from files/url/streams).
+ *
+ * @author Karl Helgason
+ */
+public class DLSSoundbank implements Soundbank {
+
+    static private class DLSID {
+        long i1;
+        int s1;
+        int s2;
+        int x1;
+        int x2;
+        int x3;
+        int x4;
+        int x5;
+        int x6;
+        int x7;
+        int x8;
+
+        private DLSID() {
+        }
+
+        public DLSID(long i1, int s1, int s2, int x1, int x2, int x3, int x4,
+                int x5, int x6, int x7, int x8) {
+            this.i1 = i1;
+            this.s1 = s1;
+            this.s2 = s2;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.x3 = x3;
+            this.x4 = x4;
+            this.x5 = x5;
+            this.x6 = x6;
+            this.x7 = x7;
+            this.x8 = x8;
+        }
+
+        public static DLSID read(RIFFReader riff) throws IOException {
+            DLSID d = new DLSID();
+            d.i1 = riff.readUnsignedInt();
+            d.s1 = riff.readUnsignedShort();
+            d.s2 = riff.readUnsignedShort();
+            d.x1 = riff.readByte();
+            d.x2 = riff.readByte();
+            d.x3 = riff.readByte();
+            d.x4 = riff.readByte();
+            d.x5 = riff.readByte();
+            d.x6 = riff.readByte();
+            d.x7 = riff.readByte();
+            d.x8 = riff.readByte();
+            return d;
+        }
+
+        public boolean equals(Object obj) {
+            if (!(obj instanceof DLSID)) {
+                return false;
+            }
+            DLSID t = (DLSID) obj;
+            return i1 == t.i1 && s1 == t.s1 && s2 == t.s2
+                && x1 == t.x1 && x2 == t.x2 && x3 == t.x3 && x4 == t.x4
+                && x5 == t.x5 && x6 == t.x6 && x7 == t.x7 && x8 == t.x8;
+        }
+    }
+
+    /** X = X & Y */
+    private static final int DLS_CDL_AND = 0x0001;
+    /** X = X | Y */
+    private static final int DLS_CDL_OR = 0x0002;
+    /** X = X ^ Y */
+    private static final int DLS_CDL_XOR = 0x0003;
+    /** X = X + Y */
+    private static final int DLS_CDL_ADD = 0x0004;
+    /** X = X - Y */
+    private static final int DLS_CDL_SUBTRACT = 0x0005;
+    /** X = X * Y */
+    private static final int DLS_CDL_MULTIPLY = 0x0006;
+    /** X = X / Y */
+    private static final int DLS_CDL_DIVIDE = 0x0007;
+    /** X = X && Y */
+    private static final int DLS_CDL_LOGICAL_AND = 0x0008;
+    /** X = X || Y */
+    private static final int DLS_CDL_LOGICAL_OR = 0x0009;
+    /** X = (X < Y) */
+    private static final int DLS_CDL_LT = 0x000A;
+    /** X = (X <= Y) */
+    private static final int DLS_CDL_LE = 0x000B;
+    /** X = (X > Y) */
+    private static final int DLS_CDL_GT = 0x000C;
+    /** X = (X >= Y) */
+    private static final int DLS_CDL_GE = 0x000D;
+    /** X = (X == Y) */
+    private static final int DLS_CDL_EQ = 0x000E;
+    /** X = !X */
+    private static final int DLS_CDL_NOT = 0x000F;
+    /** 32-bit constant */
+    private static final int DLS_CDL_CONST = 0x0010;
+    /** 32-bit value returned from query */
+    private static final int DLS_CDL_QUERY = 0x0011;
+    /** 32-bit value returned from query */
+    private static final int DLS_CDL_QUERYSUPPORTED = 0x0012;
+
+    private static final DLSID DLSID_GMInHardware = new DLSID(0x178f2f24,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_GSInHardware = new DLSID(0x178f2f25,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_XGInHardware = new DLSID(0x178f2f26,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_SupportsDLS1 = new DLSID(0x178f2f27,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_SupportsDLS2 = new DLSID(0xf14599e5,
+            0x4689, 0x11d2, 0xaf, 0xa6, 0x0, 0xaa, 0x0, 0x24, 0xd8, 0xb6);
+    private static final DLSID DLSID_SampleMemorySize = new DLSID(0x178f2f28,
+            0xc364, 0x11d1, 0xa7, 0x60, 0x00, 0x00, 0xf8, 0x75, 0xac, 0x12);
+    private static final DLSID DLSID_ManufacturersID = new DLSID(0xb03e1181,
+            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+    private static final DLSID DLSID_ProductID = new DLSID(0xb03e1182,
+            0x8095, 0x11d2, 0xa1, 0xef, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+    private static final DLSID DLSID_SamplePlaybackRate = new DLSID(0x2a91f713,
+            0xa4bf, 0x11d2, 0xbb, 0xdf, 0x0, 0x60, 0x8, 0x33, 0xdb, 0xd8);
+
+    private long major = -1;
+    private long minor = -1;
+
+    private DLSInfo info = new DLSInfo();
+
+    private List<DLSInstrument> instruments = new ArrayList<DLSInstrument>();
+    private List<DLSSample> samples = new ArrayList<DLSSample>();
+
+    private boolean largeFormat = false;
+    private File sampleFile;
+
+    public DLSSoundbank() {
+    }
+
+    public DLSSoundbank(URL url) throws IOException {
+        InputStream is = url.openStream();
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public DLSSoundbank(File file) throws IOException {
+        largeFormat = true;
+        sampleFile = file;
+        InputStream is = new FileInputStream(file);
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public DLSSoundbank(InputStream inputstream) throws IOException {
+        readSoundbank(inputstream);
+    }
+
+    private void readSoundbank(InputStream inputstream) throws IOException {
+        RIFFReader riff = new RIFFReader(inputstream);
+        if (!riff.getFormat().equals("RIFF")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid RIFF stream!");
+        }
+        if (!riff.getType().equals("DLS ")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid DLS soundbank!");
+        }
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("INFO"))
+                    readInfoChunk(chunk);
+                if (chunk.getType().equals("lins"))
+                    readLinsChunk(chunk);
+                if (chunk.getType().equals("wvpl"))
+                    readWvplChunk(chunk);
+            } else {
+                if (chunk.getFormat().equals("cdl ")) {
+                    if (!readCdlChunk(chunk)) {
+                        throw new RIFFInvalidFormatException(
+                                "DLS file isn't supported!");
+                    }
+                }
+                if (chunk.getFormat().equals("colh")) {
+                    // skipped because we will load the entire bank into memory
+                    // long instrumentcount = chunk.readUnsignedInt();
+                    // System.out.println("instrumentcount = "+ instrumentcount);
+                }
+                if (chunk.getFormat().equals("ptbl")) {
+                    // Pool Table Chunk
+                    // skipped because we will load the entire bank into memory
+                }
+                if (chunk.getFormat().equals("vers")) {
+                    major = chunk.readUnsignedInt();
+                    minor = chunk.readUnsignedInt();
+                }
+            }
+        }
+
+        for (Map.Entry<DLSRegion, Long> entry : temp_rgnassign.entrySet()) {
+            entry.getKey().sample = samples.get((int)entry.getValue().longValue());
+        }
+
+        temp_rgnassign = null;
+    }
+
+    private boolean cdlIsQuerySupported(DLSID uuid) {
+        return uuid.equals(DLSID_GMInHardware)
+            || uuid.equals(DLSID_GSInHardware)
+            || uuid.equals(DLSID_XGInHardware)
+            || uuid.equals(DLSID_SupportsDLS1)
+            || uuid.equals(DLSID_SupportsDLS2)
+            || uuid.equals(DLSID_SampleMemorySize)
+            || uuid.equals(DLSID_ManufacturersID)
+            || uuid.equals(DLSID_ProductID)
+            || uuid.equals(DLSID_SamplePlaybackRate);
+    }
+
+    private long cdlQuery(DLSID uuid) {
+        if (uuid.equals(DLSID_GMInHardware))
+            return 1;
+        if (uuid.equals(DLSID_GSInHardware))
+            return 0;
+        if (uuid.equals(DLSID_XGInHardware))
+            return 0;
+        if (uuid.equals(DLSID_SupportsDLS1))
+            return 1;
+        if (uuid.equals(DLSID_SupportsDLS2))
+            return 1;
+        if (uuid.equals(DLSID_SampleMemorySize))
+            return Runtime.getRuntime().totalMemory();
+        if (uuid.equals(DLSID_ManufacturersID))
+            return 0;
+        if (uuid.equals(DLSID_ProductID))
+            return 0;
+        if (uuid.equals(DLSID_SamplePlaybackRate))
+            return 44100;
+        return 0;
+    }
+
+
+    // Reading cdl-ck Chunk
+    // "cdl " chunk can only appear inside : DLS,lart,lar2,rgn,rgn2
+    private boolean readCdlChunk(RIFFReader riff) throws IOException {
+
+        DLSID uuid;
+        long x;
+        long y;
+        Stack<Long> stack = new Stack<Long>();
+
+        while (riff.available() != 0) {
+            int opcode = riff.readUnsignedShort();
+            switch (opcode) {
+            case DLS_CDL_AND:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(((x != 0) & (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_OR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(((x != 0) | (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_XOR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(((x != 0) ^ (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_ADD:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(x + y));
+                break;
+            case DLS_CDL_SUBTRACT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(x - y));
+                break;
+            case DLS_CDL_MULTIPLY:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(x * y));
+                break;
+            case DLS_CDL_DIVIDE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(x / y));
+                break;
+            case DLS_CDL_LOGICAL_AND:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(((x != 0) & (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_LOGICAL_OR:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long(((x != 0) | (y != 0)) ? 1 : 0));
+                break;
+            case DLS_CDL_LT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long((x < y) ? 1 : 0));
+                break;
+            case DLS_CDL_LE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long((x <= y) ? 1 : 0));
+                break;
+            case DLS_CDL_GT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long((x > y) ? 1 : 0));
+                break;
+            case DLS_CDL_GE:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long((x >= y) ? 1 : 0));
+                break;
+            case DLS_CDL_EQ:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long((x == y) ? 1 : 0));
+                break;
+            case DLS_CDL_NOT:
+                x = stack.pop();
+                y = stack.pop();
+                stack.push(new Long((x == 0) ? 1 : 0));
+                break;
+            case DLS_CDL_CONST:
+                stack.push(new Long(riff.readUnsignedInt()));
+                break;
+            case DLS_CDL_QUERY:
+                uuid = DLSID.read(riff);
+                stack.push(cdlQuery(uuid));
+                break;
+            case DLS_CDL_QUERYSUPPORTED:
+                uuid = DLSID.read(riff);
+                stack.push(new Long(cdlIsQuerySupported(uuid) ? 1 : 0));
+                break;
+            default:
+                break;
+            }
+        }
+        if (stack.isEmpty())
+            return false;
+
+        return stack.pop() == 1;
+    }
+
+    private void readInfoChunk(RIFFReader riff) throws IOException {
+        info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM"))
+                info.name = chunk.readString(chunk.available());
+            else if (format.equals("ICRD"))
+                info.creationDate = chunk.readString(chunk.available());
+            else if (format.equals("IENG"))
+                info.engineers = chunk.readString(chunk.available());
+            else if (format.equals("IPRD"))
+                info.product = chunk.readString(chunk.available());
+            else if (format.equals("ICOP"))
+                info.copyright = chunk.readString(chunk.available());
+            else if (format.equals("ICMT"))
+                info.comments = chunk.readString(chunk.available());
+            else if (format.equals("ISFT"))
+                info.tools = chunk.readString(chunk.available());
+            else if (format.equals("IARL"))
+                info.archival_location = chunk.readString(chunk.available());
+            else if (format.equals("IART"))
+                info.artist = chunk.readString(chunk.available());
+            else if (format.equals("ICMS"))
+                info.commissioned = chunk.readString(chunk.available());
+            else if (format.equals("IGNR"))
+                info.genre = chunk.readString(chunk.available());
+            else if (format.equals("IKEY"))
+                info.keywords = chunk.readString(chunk.available());
+            else if (format.equals("IMED"))
+                info.medium = chunk.readString(chunk.available());
+            else if (format.equals("ISBJ"))
+                info.subject = chunk.readString(chunk.available());
+            else if (format.equals("ISRC"))
+                info.source = chunk.readString(chunk.available());
+            else if (format.equals("ISRF"))
+                info.source_form = chunk.readString(chunk.available());
+            else if (format.equals("ITCH"))
+                info.technician = chunk.readString(chunk.available());
+        }
+    }
+
+    private void readLinsChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("ins "))
+                    readInsChunk(chunk);
+            }
+        }
+    }
+
+    private void readInsChunk(RIFFReader riff) throws IOException {
+        DLSInstrument instrument = new DLSInstrument(this);
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("INFO")) {
+                    readInsInfoChunk(instrument, chunk);
+                }
+                if (chunk.getType().equals("lrgn")) {
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (subchunk.getFormat().equals("LIST")) {
+                            if (subchunk.getType().equals("rgn ")) {
+                                DLSRegion split = new DLSRegion();
+                                if (readRgnChunk(split, subchunk))
+                                    instrument.getRegions().add(split);
+                            }
+                            if (subchunk.getType().equals("rgn2")) {
+                                // support for DLS level 2 regions
+                                DLSRegion split = new DLSRegion();
+                                if (readRgnChunk(split, subchunk))
+                                    instrument.getRegions().add(split);
+                            }
+                        }
+                    }
+                }
+                if (chunk.getType().equals("lart")) {
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art1"))
+                            readArt1Chunk(modlist, subchunk);
+                    }
+                    instrument.getModulators().addAll(modlist);
+                }
+                if (chunk.getType().equals("lar2")) {
+                    // support for DLS level 2 ART
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art2"))
+                            readArt2Chunk(modlist, subchunk);
+                    }
+                    instrument.getModulators().addAll(modlist);
+                }
+            } else {
+                if (format.equals("dlid")) {
+                    instrument.guid = new byte[16];
+                    chunk.read(instrument.guid);
+                }
+                if (format.equals("insh")) {
+                    chunk.readUnsignedInt(); // Read Region Count - ignored
+
+                    int bank = chunk.read();             // LSB
+                    bank += (chunk.read() & 127) << 7;   // MSB
+                    chunk.read(); // Read Reserved byte
+                    int drumins = chunk.read();          // Drum Instrument
+
+                    int id = chunk.read() & 127; // Read only first 7 bits
+                    chunk.read(); // Read Reserved byte
+                    chunk.read(); // Read Reserved byte
+                    chunk.read(); // Read Reserved byte
+
+                    instrument.bank = bank;
+                    instrument.preset = (int) id;
+                    instrument.druminstrument = (drumins & 128) > 0;
+                    //System.out.println("bank="+bank+" drumkit="+drumkit
+                    //        +" id="+id);
+                }
+
+            }
+        }
+        instruments.add(instrument);
+    }
+
+    private void readArt1Chunk(List<DLSModulator> modulators, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        long count = riff.readUnsignedInt();
+
+        if (size - 8 != 0)
+            riff.skip(size - 8);
+
+        for (int i = 0; i < count; i++) {
+            DLSModulator modulator = new DLSModulator();
+            modulator.version = 1;
+            modulator.source = riff.readUnsignedShort();
+            modulator.control = riff.readUnsignedShort();
+            modulator.destination = riff.readUnsignedShort();
+            modulator.transform = riff.readUnsignedShort();
+            modulator.scale = riff.readInt();
+            modulators.add(modulator);
+        }
+    }
+
+    private void readArt2Chunk(List<DLSModulator> modulators, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        long count = riff.readUnsignedInt();
+
+        if (size - 8 != 0)
+            riff.skip(size - 8);
+
+        for (int i = 0; i < count; i++) {
+            DLSModulator modulator = new DLSModulator();
+            modulator.version = 2;
+            modulator.source = riff.readUnsignedShort();
+            modulator.control = riff.readUnsignedShort();
+            modulator.destination = riff.readUnsignedShort();
+            modulator.transform = riff.readUnsignedShort();
+            modulator.scale = riff.readInt();
+            modulators.add(modulator);
+        }
+    }
+
+    private Map<DLSRegion, Long> temp_rgnassign = new HashMap<DLSRegion, Long>();
+
+    private boolean readRgnChunk(DLSRegion split, RIFFReader riff)
+            throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("lart")) {
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art1"))
+                            readArt1Chunk(modlist, subchunk);
+                    }
+                    split.getModulators().addAll(modlist);
+                }
+                if (chunk.getType().equals("lar2")) {
+                    // support for DLS level 2 ART
+                    List<DLSModulator> modlist = new ArrayList<DLSModulator>();
+                    while (chunk.hasNextChunk()) {
+                        RIFFReader subchunk = chunk.nextChunk();
+                        if (chunk.getFormat().equals("cdl ")) {
+                            if (!readCdlChunk(chunk)) {
+                                modlist.clear();
+                                break;
+                            }
+                        }
+                        if (subchunk.getFormat().equals("art2"))
+                            readArt2Chunk(modlist, subchunk);
+                    }
+                    split.getModulators().addAll(modlist);
+                }
+            } else {
+
+                if (format.equals("cdl ")) {
+                    if (!readCdlChunk(chunk))
+                        return false;
+                }
+                if (format.equals("rgnh")) {
+                    split.keyfrom = chunk.readUnsignedShort();
+                    split.keyto = chunk.readUnsignedShort();
+                    split.velfrom = chunk.readUnsignedShort();
+                    split.velto = chunk.readUnsignedShort();
+                    split.options = chunk.readUnsignedShort();
+                    split.exclusiveClass = chunk.readUnsignedShort();
+                }
+                if (format.equals("wlnk")) {
+                    split.fusoptions = chunk.readUnsignedShort();
+                    split.phasegroup = chunk.readUnsignedShort();
+                    split.channel = chunk.readUnsignedInt();
+                    long sampleid = chunk.readUnsignedInt();
+                    temp_rgnassign.put(split, sampleid);
+                }
+                if (format.equals("wsmp")) {
+                    split.sampleoptions = new DLSSampleOptions();
+                    readWsmpChunk(split.sampleoptions, chunk);
+                }
+            }
+        }
+        return true;
+    }
+
+    private void readWsmpChunk(DLSSampleOptions sampleOptions, RIFFReader riff)
+            throws IOException {
+        long size = riff.readUnsignedInt();
+        sampleOptions.unitynote = riff.readUnsignedShort();
+        sampleOptions.finetune = riff.readShort();
+        sampleOptions.attenuation = riff.readInt();
+        sampleOptions.options = riff.readUnsignedInt();
+        long loops = riff.readInt();
+
+        if (size > 20)
+            riff.skip(size - 20);
+
+        for (int i = 0; i < loops; i++) {
+            DLSSampleLoop loop = new DLSSampleLoop();
+            long size2 = riff.readUnsignedInt();
+            loop.type = riff.readUnsignedInt();
+            loop.start = riff.readUnsignedInt();
+            loop.length = riff.readUnsignedInt();
+            sampleOptions.loops.add(loop);
+            if (size2 > 16)
+                riff.skip(size2 - 16);
+        }
+    }
+
+    private void readInsInfoChunk(DLSInstrument dlsinstrument, RIFFReader riff)
+            throws IOException {
+        dlsinstrument.info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM")) {
+                dlsinstrument.info.name = chunk.readString(chunk.available());
+            } else if (format.equals("ICRD")) {
+                dlsinstrument.info.creationDate =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                dlsinstrument.info.engineers =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                dlsinstrument.info.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                dlsinstrument.info.copyright =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                dlsinstrument.info.comments =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                dlsinstrument.info.tools = chunk.readString(chunk.available());
+            } else if (format.equals("IARL")) {
+                dlsinstrument.info.archival_location =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IART")) {
+                dlsinstrument.info.artist = chunk.readString(chunk.available());
+            } else if (format.equals("ICMS")) {
+                dlsinstrument.info.commissioned =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IGNR")) {
+                dlsinstrument.info.genre = chunk.readString(chunk.available());
+            } else if (format.equals("IKEY")) {
+                dlsinstrument.info.keywords =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IMED")) {
+                dlsinstrument.info.medium = chunk.readString(chunk.available());
+            } else if (format.equals("ISBJ")) {
+                dlsinstrument.info.subject = chunk.readString(chunk.available());
+            } else if (format.equals("ISRC")) {
+                dlsinstrument.info.source = chunk.readString(chunk.available());
+            } else if (format.equals("ISRF")) {
+                dlsinstrument.info.source_form =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("ITCH")) {
+                dlsinstrument.info.technician =
+                        chunk.readString(chunk.available());
+            }
+        }
+    }
+
+    private void readWvplChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("wave"))
+                    readWaveChunk(chunk);
+            }
+        }
+    }
+
+    private void readWaveChunk(RIFFReader riff) throws IOException {
+        DLSSample sample = new DLSSample(this);
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("LIST")) {
+                if (chunk.getType().equals("INFO")) {
+                    readWaveInfoChunk(sample, chunk);
+                }
+            } else {
+                if (format.equals("dlid")) {
+                    sample.guid = new byte[16];
+                    chunk.read(sample.guid);
+                }
+
+                if (format.equals("fmt ")) {
+                    int sampleformat = chunk.readUnsignedShort();
+                    if (sampleformat != 1 && sampleformat != 3) {
+                        throw new RIFFInvalidDataException(
+                                "Only PCM samples are supported!");
+                    }
+                    int channels = chunk.readUnsignedShort();
+                    long samplerate = chunk.readUnsignedInt();
+                    // bytes per sec
+                    /* long framerate = */ chunk.readUnsignedInt();
+                    // block align, framesize
+                    int framesize = chunk.readUnsignedShort();
+                    int bits = chunk.readUnsignedShort();
+                    AudioFormat audioformat = null;
+                    if (sampleformat == 1) {
+                        if (bits == 8) {
+                            audioformat = new AudioFormat(
+                                    Encoding.PCM_UNSIGNED, samplerate, bits,
+                                    channels, framesize, samplerate, false);
+                        } else {
+                            audioformat = new AudioFormat(
+                                    Encoding.PCM_SIGNED, samplerate, bits,
+                                    channels, framesize, samplerate, false);
+                        }
+                    }
+                    if (sampleformat == 3) {
+                        audioformat = new AudioFormat(
+                                AudioFloatConverter.PCM_FLOAT, samplerate, bits,
+                                channels, framesize, samplerate, false);
+                    }
+
+                    sample.format = audioformat;
+                }
+
+                if (format.equals("data")) {
+                    if (largeFormat) {
+                        sample.setData(new ModelByteBuffer(sampleFile,
+                                chunk.getFilePointer(), chunk.available()));
+                    } else {
+                        byte[] buffer = new byte[chunk.available()];
+                        //      chunk.read(buffer);
+                        sample.setData(buffer);
+
+                        int read = 0;
+                        int avail = chunk.available();
+                        while (read != avail) {
+                            if (avail - read > 65536) {
+                                chunk.read(buffer, read, 65536);
+                                read += 65536;
+                            } else {
+                                chunk.read(buffer, read, avail - read);
+                                read = avail;
+                            }
+                        }
+                    }
+                }
+
+                if (format.equals("wsmp")) {
+                    sample.sampleoptions = new DLSSampleOptions();
+                    readWsmpChunk(sample.sampleoptions, chunk);
+                }
+            }
+        }
+
+        samples.add(sample);
+
+    }
+
+    private void readWaveInfoChunk(DLSSample dlssample, RIFFReader riff)
+            throws IOException {
+        dlssample.info.name = null;
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("INAM")) {
+                dlssample.info.name = chunk.readString(chunk.available());
+            } else if (format.equals("ICRD")) {
+                dlssample.info.creationDate =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                dlssample.info.engineers = chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                dlssample.info.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                dlssample.info.copyright = chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                dlssample.info.comments = chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                dlssample.info.tools = chunk.readString(chunk.available());
+            } else if (format.equals("IARL")) {
+                dlssample.info.archival_location =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IART")) {
+                dlssample.info.artist = chunk.readString(chunk.available());
+            } else if (format.equals("ICMS")) {
+                dlssample.info.commissioned =
+                        chunk.readString(chunk.available());
+            } else if (format.equals("IGNR")) {
+                dlssample.info.genre = chunk.readString(chunk.available());
+            } else if (format.equals("IKEY")) {
+                dlssample.info.keywords = chunk.readString(chunk.available());
+            } else if (format.equals("IMED")) {
+                dlssample.info.medium = chunk.readString(chunk.available());
+            } else if (format.equals("ISBJ")) {
+                dlssample.info.subject = chunk.readString(chunk.available());
+            } else if (format.equals("ISRC")) {
+                dlssample.info.source = chunk.readString(chunk.available());
+            } else if (format.equals("ISRF")) {
+                dlssample.info.source_form = chunk.readString(chunk.available());
+            } else if (format.equals("ITCH")) {
+                dlssample.info.technician = chunk.readString(chunk.available());
+            }
+        }
+    }
+
+    public void save(String name) throws IOException {
+        writeSoundbank(new RIFFWriter(name, "DLS "));
+    }
+
+    public void save(File file) throws IOException {
+        writeSoundbank(new RIFFWriter(file, "DLS "));
+    }
+
+    public void save(OutputStream out) throws IOException {
+        writeSoundbank(new RIFFWriter(out, "DLS "));
+    }
+
+    private void writeSoundbank(RIFFWriter writer) throws IOException {
+        RIFFWriter colh_chunk = writer.writeChunk("colh");
+        colh_chunk.writeUnsignedInt(instruments.size());
+
+        if (major != -1 && minor != -1) {
+            RIFFWriter vers_chunk = writer.writeChunk("vers");
+            vers_chunk.writeUnsignedInt(major);
+            vers_chunk.writeUnsignedInt(minor);
+        }
+
+        writeInstruments(writer.writeList("lins"));
+
+        RIFFWriter ptbl = writer.writeChunk("ptbl");
+        ptbl.writeUnsignedInt(8);
+        ptbl.writeUnsignedInt(samples.size());
+        long ptbl_offset = writer.getFilePointer();
+        for (int i = 0; i < samples.size(); i++)
+            ptbl.writeUnsignedInt(0);
+
+        RIFFWriter wvpl = writer.writeList("wvpl");
+        long off = wvpl.getFilePointer();
+        List<Long> offsettable = new ArrayList<Long>();
+        for (DLSSample sample : samples) {
+            offsettable.add(new Long(wvpl.getFilePointer() - off));
+            writeSample(wvpl.writeList("wave"), sample);
+        }
+
+        // small cheat, we are going to rewrite data back in wvpl
+        long bak = writer.getFilePointer();
+        writer.seek(ptbl_offset);
+        writer.setWriteOverride(true);
+        for (Long offset : offsettable)
+            writer.writeUnsignedInt(offset.longValue());
+        writer.setWriteOverride(false);
+        writer.seek(bak);
+
+        writeInfo(writer.writeList("INFO"), info);
+
+        writer.close();
+    }
+
+    private void writeSample(RIFFWriter writer, DLSSample sample)
+            throws IOException {
+
+        AudioFormat audioformat = sample.getFormat();
+
+        Encoding encoding = audioformat.getEncoding();
+        float sampleRate = audioformat.getSampleRate();
+        int sampleSizeInBits = audioformat.getSampleSizeInBits();
+        int channels = audioformat.getChannels();
+        int frameSize = audioformat.getFrameSize();
+        float frameRate = audioformat.getFrameRate();
+        boolean bigEndian = audioformat.isBigEndian();
+
+        boolean convert_needed = false;
+
+        if (audioformat.getSampleSizeInBits() == 8) {
+            if (!encoding.equals(Encoding.PCM_UNSIGNED)) {
+                encoding = Encoding.PCM_UNSIGNED;
+                convert_needed = true;
+            }
+        } else {
+            if (!encoding.equals(Encoding.PCM_SIGNED)) {
+                encoding = Encoding.PCM_SIGNED;
+                convert_needed = true;
+            }
+            if (bigEndian) {
+                bigEndian = false;
+                convert_needed = true;
+            }
+        }
+
+        if (convert_needed) {
+            audioformat = new AudioFormat(encoding, sampleRate,
+                    sampleSizeInBits, channels, frameSize, frameRate, bigEndian);
+        }
+
+        // fmt
+        RIFFWriter fmt_chunk = writer.writeChunk("fmt ");
+        int sampleformat = 0;
+        if (audioformat.getEncoding().equals(Encoding.PCM_UNSIGNED))
+            sampleformat = 1;
+        else if (audioformat.getEncoding().equals(Encoding.PCM_SIGNED))
+            sampleformat = 1;
+        else if (audioformat.getEncoding().equals(AudioFloatConverter.PCM_FLOAT))
+            sampleformat = 3;
+
+        fmt_chunk.writeUnsignedShort(sampleformat);
+        fmt_chunk.writeUnsignedShort(audioformat.getChannels());
+        fmt_chunk.writeUnsignedInt((long) audioformat.getSampleRate());
+        long srate = (long)audioformat.getSampleRate();
+        srate *= audioformat.getChannels();
+        srate *= audioformat.getSampleSizeInBits() / 8;
+        //fmt_chunk.writeUnsignedInt((long)audioformat.getFrameRate());
+        fmt_chunk.writeUnsignedInt(srate);
+        fmt_chunk.writeUnsignedShort(audioformat.getFrameSize());
+        fmt_chunk.writeUnsignedShort(audioformat.getSampleSizeInBits());
+        fmt_chunk.write(0);
+        fmt_chunk.write(0);
+
+        writeSampleOptions(writer.writeChunk("wsmp"), sample.sampleoptions);
+
+        if (convert_needed) {
+            RIFFWriter data_chunk = writer.writeChunk("data");
+            AudioInputStream stream = AudioSystem.getAudioInputStream(
+                    audioformat, (AudioInputStream)sample.getData());
+            byte[] buff = new byte[1024];
+            int ret;
+            while ((ret = stream.read(buff)) != -1) {
+                data_chunk.write(buff, 0, ret);
+            }
+        } else {
+            RIFFWriter data_chunk = writer.writeChunk("data");
+            ModelByteBuffer databuff = sample.getDataBuffer();
+            databuff.writeTo(data_chunk);
+            /*
+            data_chunk.write(databuff.array(),
+            databuff.arrayOffset(),
+            databuff.capacity());
+             */
+        }
+
+        writeInfo(writer.writeList("INFO"), sample.info);
+    }
+
+    private void writeInstruments(RIFFWriter writer) throws IOException {
+        for (DLSInstrument instrument : instruments) {
+            writeInstrument(writer.writeList("ins "), instrument);
+        }
+    }
+
+    private void writeInstrument(RIFFWriter writer, DLSInstrument instrument)
+            throws IOException {
+
+        int art1_count = 0;
+        int art2_count = 0;
+        for (DLSModulator modulator : instrument.getModulators()) {
+            if (modulator.version == 1)
+                art1_count++;
+            if (modulator.version == 2)
+                art2_count++;
+        }
+        for (DLSRegion region : instrument.regions) {
+            for (DLSModulator modulator : region.getModulators()) {
+                if (modulator.version == 1)
+                    art1_count++;
+                if (modulator.version == 2)
+                    art2_count++;
+            }
+        }
+
+        int version = 1;
+        if (art2_count > 0)
+            version = 2;
+
+        RIFFWriter insh_chunk = writer.writeChunk("insh");
+        insh_chunk.writeUnsignedInt(instrument.getRegions().size());
+        insh_chunk.writeUnsignedInt(instrument.bank +
+                (instrument.druminstrument ? 2147483648L : 0));
+        insh_chunk.writeUnsignedInt(instrument.preset);
+
+        RIFFWriter lrgn = writer.writeList("lrgn");
+        for (DLSRegion region: instrument.regions)
+            writeRegion(lrgn, region, version);
+
+        writeArticulators(writer, instrument.getModulators());
+
+        writeInfo(writer.writeList("INFO"), instrument.info);
+
+    }
+
+    private void writeArticulators(RIFFWriter writer,
+            List<DLSModulator> modulators) throws IOException {
+        int art1_count = 0;
+        int art2_count = 0;
+        for (DLSModulator modulator : modulators) {
+            if (modulator.version == 1)
+                art1_count++;
+            if (modulator.version == 2)
+                art2_count++;
+        }
+        if (art1_count > 0) {
+            RIFFWriter lar1 = writer.writeList("lart");
+            RIFFWriter art1 = lar1.writeChunk("art1");
+            art1.writeUnsignedInt(8);
+            art1.writeUnsignedInt(art1_count);
+            for (DLSModulator modulator : modulators) {
+                if (modulator.version == 1) {
+                    art1.writeUnsignedShort(modulator.source);
+                    art1.writeUnsignedShort(modulator.control);
+                    art1.writeUnsignedShort(modulator.destination);
+                    art1.writeUnsignedShort(modulator.transform);
+                    art1.writeInt(modulator.scale);
+                }
+            }
+        }
+        if (art2_count > 0) {
+            RIFFWriter lar2 = writer.writeList("lar2");
+            RIFFWriter art2 = lar2.writeChunk("art2");
+            art2.writeUnsignedInt(8);
+            art2.writeUnsignedInt(art2_count);
+            for (DLSModulator modulator : modulators) {
+                if (modulator.version == 2) {
+                    art2.writeUnsignedShort(modulator.source);
+                    art2.writeUnsignedShort(modulator.control);
+                    art2.writeUnsignedShort(modulator.destination);
+                    art2.writeUnsignedShort(modulator.transform);
+                    art2.writeInt(modulator.scale);
+                }
+            }
+        }
+    }
+
+    private void writeRegion(RIFFWriter writer, DLSRegion region, int version)
+            throws IOException {
+        RIFFWriter rgns = null;
+        if (version == 1)
+            rgns = writer.writeList("rgn ");
+        if (version == 2)
+            rgns = writer.writeList("rgn2");
+        if (rgns == null)
+            return;
+
+        RIFFWriter rgnh = rgns.writeChunk("rgnh");
+        rgnh.writeUnsignedShort(region.keyfrom);
+        rgnh.writeUnsignedShort(region.keyto);
+        rgnh.writeUnsignedShort(region.velfrom);
+        rgnh.writeUnsignedShort(region.velto);
+        rgnh.writeUnsignedShort(region.options);
+        rgnh.writeUnsignedShort(region.exclusiveClass);
+
+        if (region.sampleoptions != null)
+            writeSampleOptions(rgns.writeChunk("wsmp"), region.sampleoptions);
+
+        if (region.sample != null) {
+            if (samples.indexOf(region.sample) != -1) {
+                RIFFWriter wlnk = rgns.writeChunk("wlnk");
+                wlnk.writeUnsignedShort(region.fusoptions);
+                wlnk.writeUnsignedShort(region.phasegroup);
+                wlnk.writeUnsignedInt(region.channel);
+                wlnk.writeUnsignedInt(samples.indexOf(region.sample));
+            }
+        }
+        writeArticulators(rgns, region.getModulators());
+        rgns.close();
+    }
+
+    private void writeSampleOptions(RIFFWriter wsmp,
+            DLSSampleOptions sampleoptions) throws IOException {
+        wsmp.writeUnsignedInt(20);
+        wsmp.writeUnsignedShort(sampleoptions.unitynote);
+        wsmp.writeShort(sampleoptions.finetune);
+        wsmp.writeInt(sampleoptions.attenuation);
+        wsmp.writeUnsignedInt(sampleoptions.options);
+        wsmp.writeInt(sampleoptions.loops.size());
+
+        for (DLSSampleLoop loop : sampleoptions.loops) {
+            wsmp.writeUnsignedInt(16);
+            wsmp.writeUnsignedInt(loop.type);
+            wsmp.writeUnsignedInt(loop.start);
+            wsmp.writeUnsignedInt(loop.length);
+        }
+    }
+
+    private void writeInfoStringChunk(RIFFWriter writer,
+            String name, String value) throws IOException {
+        if (value == null)
+            return;
+        RIFFWriter chunk = writer.writeChunk(name);
+        chunk.writeString(value);
+        int len = value.getBytes("ascii").length;
+        chunk.write(0);
+        len++;
+        if (len % 2 != 0)
+            chunk.write(0);
+    }
+
+    private void writeInfo(RIFFWriter writer, DLSInfo info) throws IOException {
+        writeInfoStringChunk(writer, "INAM", info.name);
+        writeInfoStringChunk(writer, "ICRD", info.creationDate);
+        writeInfoStringChunk(writer, "IENG", info.engineers);
+        writeInfoStringChunk(writer, "IPRD", info.product);
+        writeInfoStringChunk(writer, "ICOP", info.copyright);
+        writeInfoStringChunk(writer, "ICMT", info.comments);
+        writeInfoStringChunk(writer, "ISFT", info.tools);
+        writeInfoStringChunk(writer, "IARL", info.archival_location);
+        writeInfoStringChunk(writer, "IART", info.artist);
+        writeInfoStringChunk(writer, "ICMS", info.commissioned);
+        writeInfoStringChunk(writer, "IGNR", info.genre);
+        writeInfoStringChunk(writer, "IKEY", info.keywords);
+        writeInfoStringChunk(writer, "IMED", info.medium);
+        writeInfoStringChunk(writer, "ISBJ", info.subject);
+        writeInfoStringChunk(writer, "ISRC", info.source);
+        writeInfoStringChunk(writer, "ISRF", info.source_form);
+        writeInfoStringChunk(writer, "ITCH", info.technician);
+    }
+
+    public DLSInfo getInfo() {
+        return info;
+    }
+
+    public String getName() {
+        return info.name;
+    }
+
+    public String getVersion() {
+        return major + "." + minor;
+    }
+
+    public String getVendor() {
+        return info.engineers;
+    }
+
+    public String getDescription() {
+        return info.comments;
+    }
+
+    public void setName(String s) {
+        info.name = s;
+    }
+
+    public void setVendor(String s) {
+        info.engineers = s;
+    }
+
+    public void setDescription(String s) {
+        info.comments = s;
+    }
+
+    public SoundbankResource[] getResources() {
+        SoundbankResource[] resources = new SoundbankResource[samples.size()];
+        int j = 0;
+        for (int i = 0; i < samples.size(); i++)
+            resources[j++] = samples.get(i);
+        return resources;
+    }
+
+    public DLSInstrument[] getInstruments() {
+        DLSInstrument[] inslist_array =
+                instruments.toArray(new DLSInstrument[instruments.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public DLSSample[] getSamples() {
+        return samples.toArray(new DLSSample[samples.size()]);
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch) patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch) patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof DLSInstrument)
+            instruments.add((DLSInstrument) resource);
+        if (resource instanceof DLSSample)
+            samples.add((DLSSample) resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof DLSInstrument)
+            instruments.remove((DLSInstrument) resource);
+        if (resource instanceof DLSSample)
+            samples.remove((DLSSample) resource);
+    }
+
+    public void addInstrument(DLSInstrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(DLSInstrument resource) {
+        instruments.remove(resource);
+    }
+
+    public long getMajor() {
+        return major;
+    }
+
+    public void setMajor(long major) {
+        this.major = major;
+    }
+
+    public long getMinor() {
+        return minor;
+    }
+
+    public void setMinor(long minor) {
+        this.minor = minor;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/DLSSoundbankReader.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,74 +1,74 @@
-/*
-  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
-  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-  *
-  * This code is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU General Public License version 2 only, as
-  * published by the Free Software Foundation.  Sun designates this
-  * particular file as subject to the "Classpath" exception as provided
-  * by Sun in the LICENSE file that accompanied this code.
-  *
-  * This code is distributed in the hope that it will be useful, but WITHOUT
-  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-  * version 2 for more details (a copy is included in the LICENSE file that
-  * accompanied this code).
-  *
-  * You should have received a copy of the GNU General Public License version
-  * 2 along with this work; if not, write to the Free Software Foundation,
-  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-  *
-  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
-  * CA 95054 USA or visit www.sun.com if you need additional information or
-  * have any questions.
-  */
-
-package com.sun.media.sound;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.spi.SoundbankReader;
-
-/**
- * This class is used to connect the DLSSoundBank class
- * to the SoundbankReader SPI interface.
- *
- * @author Karl Helgason
- */
-public class DLSSoundbankReader extends SoundbankReader {
-
-    public Soundbank getSoundbank(URL url)
-            throws InvalidMidiDataException, IOException {
-        try {
-            return new DLSSoundbank(url);
-        } catch (RIFFInvalidFormatException e) {
-            return null;
-        }
-    }
-
-    public Soundbank getSoundbank(InputStream stream)
-            throws InvalidMidiDataException, IOException {
-        try {
-            stream.mark(512);
-            return new DLSSoundbank(stream);
-        } catch (RIFFInvalidFormatException e) {
-            stream.reset();
-            return null;
-        }
-    }
-
-    public Soundbank getSoundbank(File file)
-            throws InvalidMidiDataException, IOException {
-        if (!file.getPath().toLowerCase().endsWith(".dls"))
-            return null;
-        try {
-            return new DLSSoundbank(file);
-        } catch (RIFFInvalidFormatException e) {
-            return null;
-        }
-    }
-}
+/*
+  * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU General Public License version 2 only, as
+  * published by the Free Software Foundation.  Sun designates this
+  * particular file as subject to the "Classpath" exception as provided
+  * by Sun in the LICENSE file that accompanied this code.
+  *
+  * This code is distributed in the hope that it will be useful, but WITHOUT
+  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+  * version 2 for more details (a copy is included in the LICENSE file that
+  * accompanied this code).
+  *
+  * You should have received a copy of the GNU General Public License version
+  * 2 along with this work; if not, write to the Free Software Foundation,
+  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+  *
+  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+  * CA 95054 USA or visit www.sun.com if you need additional information or
+  * have any questions.
+  */
+
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * This class is used to connect the DLSSoundBank class
+ * to the SoundbankReader SPI interface.
+ *
+ * @author Karl Helgason
+ */
+public class DLSSoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new DLSSoundbank(url);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        try {
+            stream.mark(512);
+            return new DLSSoundbank(stream);
+        } catch (RIFFInvalidFormatException e) {
+            stream.reset();
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        if (!file.getPath().toLowerCase().endsWith(".dls"))
+            return null;
+        try {
+            return new DLSSoundbank(file);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/EmergencySoundbank.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,2695 +1,2695 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.Random;
-
-import javax.sound.midi.Patch;
-import javax.sound.sampled.AudioFormat;
-
-/**
- * Emergency Soundbank generator.
- * Used when no other default soundbank can be found.
- *
- * @author Karl Helgason
- */
-public class EmergencySoundbank {
-
-    public static String[] general_midi_instruments = {
-        "Acoustic Grand Piano",
-        "Bright Acoustic Piano",
-        "Electric Grand Piano",
-        "Honky-tonk Piano",
-        "Electric Piano 1",
-        "Electric Piano 2",
-        "Harpsichord",
-        "Clavi",
-        "Celesta",
-        "Glockenspiel",
-        "Music Box",
-        "Vibraphone",
-        "Marimba",
-        "Xylophone",
-        "Tubular Bells",
-        "Dulcimer",
-        "Drawbar Organ",
-        "Percussive Organ",
-        "Rock Organ",
-        "Church Organ",
-        "Reed Organ",
-        "Accordion",
-        "Harmonica",
-        "Tango Accordion",
-        "Acoustic Guitar (nylon)",
-        "Acoustic Guitar (steel)",
-        "Electric Guitar (jazz)",
-        "Electric Guitar (clean)",
-        "Electric Guitar (muted)",
-        "Overdriven Guitar",
-        "Distortion Guitar",
-        "Guitar harmonics",
-        "Acoustic Bass",
-        "Electric Bass (finger)",
-        "Electric Bass (pick)",
-        "Fretless Bass",
-        "Slap Bass 1",
-        "Slap Bass 2",
-        "Synth Bass 1",
-        "Synth Bass 2",
-        "Violin",
-        "Viola",
-        "Cello",
-        "Contrabass",
-        "Tremolo Strings",
-        "Pizzicato Strings",
-        "Orchestral Harp",
-        "Timpani",
-        "String Ensemble 1",
-        "String Ensemble 2",
-        "SynthStrings 1",
-        "SynthStrings 2",
-        "Choir Aahs",
-        "Voice Oohs",
-        "Synth Voice",
-        "Orchestra Hit",
-        "Trumpet",
-        "Trombone",
-        "Tuba",
-        "Muted Trumpet",
-        "French Horn",
-        "Brass Section",
-        "SynthBrass 1",
-        "SynthBrass 2",
-        "Soprano Sax",
-        "Alto Sax",
-        "Tenor Sax",
-        "Baritone Sax",
-        "Oboe",
-        "English Horn",
-        "Bassoon",
-        "Clarinet",
-        "Piccolo",
-        "Flute",
-        "Recorder",
-        "Pan Flute",
-        "Blown Bottle",
-        "Shakuhachi",
-        "Whistle",
-        "Ocarina",
-        "Lead 1 (square)",
-        "Lead 2 (sawtooth)",
-        "Lead 3 (calliope)",
-        "Lead 4 (chiff)",
-        "Lead 5 (charang)",
-        "Lead 6 (voice)",
-        "Lead 7 (fifths)",
-        "Lead 8 (bass + lead)",
-        "Pad 1 (new age)",
-        "Pad 2 (warm)",
-        "Pad 3 (polysynth)",
-        "Pad 4 (choir)",
-        "Pad 5 (bowed)",
-        "Pad 6 (metallic)",
-        "Pad 7 (halo)",
-        "Pad 8 (sweep)",
-        "FX 1 (rain)",
-        "FX 2 (soundtrack)",
-        "FX 3 (crystal)",
-        "FX 4 (atmosphere)",
-        "FX 5 (brightness)",
-        "FX 6 (goblins)",
-        "FX 7 (echoes)",
-        "FX 8 (sci-fi)",
-        "Sitar",
-        "Banjo",
-        "Shamisen",
-        "Koto",
-        "Kalimba",
-        "Bag pipe",
-        "Fiddle",
-        "Shanai",
-        "Tinkle Bell",
-        "Agogo",
-        "Steel Drums",
-        "Woodblock",
-        "Taiko Drum",
-        "Melodic Tom",
-        "Synth Drum",
-        "Reverse Cymbal",
-        "Guitar Fret Noise",
-        "Breath Noise",
-        "Seashore",
-        "Bird Tweet",
-        "Telephone Ring",
-        "Helicopter",
-        "Applause",
-        "Gunshot"
-    };
-
-    public static SF2Soundbank createSoundbank() throws Exception {
-        SF2Soundbank sf2 = new SF2Soundbank();
-        sf2.setName("Emergency GM sound set");
-        sf2.setVendor("Generated");
-        sf2.setDescription("Emergency generated soundbank");
-
-        /*
-         *  percussion instruments
-         */
-
-        SF2Layer bass_drum = new_bass_drum(sf2);
-        SF2Layer snare_drum = new_snare_drum(sf2);
-        SF2Layer tom = new_tom(sf2);
-        SF2Layer open_hihat = new_open_hihat(sf2);
-        SF2Layer closed_hihat = new_closed_hihat(sf2);
-        SF2Layer crash_cymbal = new_crash_cymbal(sf2);
-        SF2Layer side_stick = new_side_stick(sf2);
-
-        SF2Layer[] drums = new SF2Layer[128];
-        drums[35] = bass_drum;
-        drums[36] = bass_drum;
-        drums[38] = snare_drum;
-        drums[40] = snare_drum;
-        drums[41] = tom;
-        drums[43] = tom;
-        drums[45] = tom;
-        drums[47] = tom;
-        drums[48] = tom;
-        drums[50] = tom;
-        drums[42] = closed_hihat;
-        drums[44] = closed_hihat;
-        drums[46] = open_hihat;
-        drums[49] = crash_cymbal;
-        drums[51] = crash_cymbal;
-        drums[52] = crash_cymbal;
-        drums[55] = crash_cymbal;
-        drums[57] = crash_cymbal;
-        drums[59] = crash_cymbal;
-
-        // Use side_stick for missing drums:
-        drums[37] = side_stick;
-        drums[39] = side_stick;
-        drums[53] = side_stick;
-        drums[54] = side_stick;
-        drums[56] = side_stick;
-        drums[58] = side_stick;
-        drums[69] = side_stick;
-        drums[70] = side_stick;
-        drums[75] = side_stick;
-        drums[60] = side_stick;
-        drums[61] = side_stick;
-        drums[62] = side_stick;
-        drums[63] = side_stick;
-        drums[64] = side_stick;
-        drums[65] = side_stick;
-        drums[66] = side_stick;
-        drums[67] = side_stick;
-        drums[68] = side_stick;
-        drums[71] = side_stick;
-        drums[72] = side_stick;
-        drums[73] = side_stick;
-        drums[74] = side_stick;
-        drums[76] = side_stick;
-        drums[77] = side_stick;
-        drums[78] = side_stick;
-        drums[79] = side_stick;
-        drums[80] = side_stick;
-        drums[81] = side_stick;
-
-
-        SF2Instrument drum_instrument = new SF2Instrument(sf2);
-        drum_instrument.setName("Standard Kit");
-        drum_instrument.setPatch(new ModelPatch(0, 0, true));
-        sf2.addInstrument(drum_instrument);
-        for (int i = 0; i < drums.length; i++) {
-            if (drums[i] != null) {
-                SF2InstrumentRegion region = new SF2InstrumentRegion();
-                region.setLayer(drums[i]);
-                region.putBytes(SF2InstrumentRegion.GENERATOR_KEYRANGE,
-                        new byte[]{(byte) i, (byte) i});
-                drum_instrument.getRegions().add(region);
-            }
-        }
-
-
-        /*
-         *  melodic instruments
-         */
-
-        SF2Layer gpiano = new_gpiano(sf2);
-        SF2Layer gpiano2 = new_gpiano2(sf2);
-        SF2Layer gpiano_hammer = new_piano_hammer(sf2);
-        SF2Layer piano1 = new_piano1(sf2);
-        SF2Layer epiano1 = new_epiano1(sf2);
-        SF2Layer epiano2 = new_epiano2(sf2);
-
-        SF2Layer guitar = new_guitar1(sf2);
-        SF2Layer guitar_pick = new_guitar_pick(sf2);
-        SF2Layer guitar_dist = new_guitar_dist(sf2);
-        SF2Layer bass1 = new_bass1(sf2);
-        SF2Layer bass2 = new_bass2(sf2);
-        SF2Layer synthbass = new_synthbass(sf2);
-        SF2Layer string2 = new_string2(sf2);
-        SF2Layer orchhit = new_orchhit(sf2);
-        SF2Layer choir = new_choir(sf2);
-        SF2Layer solostring = new_solostring(sf2);
-        SF2Layer organ = new_organ(sf2);
-        SF2Layer ch_organ = new_ch_organ(sf2);
-        SF2Layer bell = new_bell(sf2);
-        SF2Layer flute = new_flute(sf2);
-
-        SF2Layer timpani = new_timpani(sf2);
-        SF2Layer melodic_toms = new_melodic_toms(sf2);
-        SF2Layer trumpet = new_trumpet(sf2);
-        SF2Layer trombone = new_trombone(sf2);
-        SF2Layer brass_section = new_brass_section(sf2);
-        SF2Layer horn = new_horn(sf2);
-        SF2Layer sax = new_sax(sf2);
-        SF2Layer oboe = new_oboe(sf2);
-        SF2Layer bassoon = new_bassoon(sf2);
-        SF2Layer clarinet = new_clarinet(sf2);
-        SF2Layer reverse_cymbal = new_reverse_cymbal(sf2);
-
-        SF2Layer defaultsound = piano1;
-
-        newInstrument(sf2, "Piano", new Patch(0, 0), gpiano, gpiano_hammer);
-        newInstrument(sf2, "Piano", new Patch(0, 1), gpiano2, gpiano_hammer);
-        newInstrument(sf2, "Piano", new Patch(0, 2), piano1);
-        {
-            SF2Instrument ins = newInstrument(sf2, "Honky-tonk Piano",
-                    new Patch(0, 3), piano1, piano1);
-            SF2InstrumentRegion region = ins.getRegions().get(0);
-            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 80);
-            region.putInteger(SF2Region.GENERATOR_FINETUNE, 30);
-            region = ins.getRegions().get(1);
-            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 30);
-        }
-        newInstrument(sf2, "Rhodes", new Patch(0, 4), epiano2);
-        newInstrument(sf2, "Rhodes", new Patch(0, 5), epiano2);
-        newInstrument(sf2, "Clavinet", new Patch(0, 6), epiano1);
-        newInstrument(sf2, "Clavinet", new Patch(0, 7), epiano1);
-        newInstrument(sf2, "Rhodes", new Patch(0, 8), epiano2);
-        newInstrument(sf2, "Bell", new Patch(0, 9), bell);
-        newInstrument(sf2, "Bell", new Patch(0, 10), bell);
-        newInstrument(sf2, "Vibraphone", new Patch(0, 11), bell);
-        newInstrument(sf2, "Marimba", new Patch(0, 12), bell);
-        newInstrument(sf2, "Marimba", new Patch(0, 13), bell);
-        newInstrument(sf2, "Bell", new Patch(0, 14), bell);
-        newInstrument(sf2, "Rock Organ", new Patch(0, 15), organ);
-        newInstrument(sf2, "Rock Organ", new Patch(0, 16), organ);
-        newInstrument(sf2, "Perc Organ", new Patch(0, 17), organ);
-        newInstrument(sf2, "Rock Organ", new Patch(0, 18), organ);
-        newInstrument(sf2, "Church Organ", new Patch(0, 19), ch_organ);
-        newInstrument(sf2, "Accordion", new Patch(0, 20), organ);
-        newInstrument(sf2, "Accordion", new Patch(0, 21), organ);
-        newInstrument(sf2, "Accordion", new Patch(0, 22), organ);
-        newInstrument(sf2, "Accordion", new Patch(0, 23), organ);
-        newInstrument(sf2, "Guitar", new Patch(0, 24), guitar, guitar_pick);
-        newInstrument(sf2, "Guitar", new Patch(0, 25), guitar, guitar_pick);
-        newInstrument(sf2, "Guitar", new Patch(0, 26), guitar, guitar_pick);
-        newInstrument(sf2, "Guitar", new Patch(0, 27), guitar, guitar_pick);
-        newInstrument(sf2, "Guitar", new Patch(0, 28), guitar, guitar_pick);
-        newInstrument(sf2, "Distorted Guitar", new Patch(0, 29), guitar_dist);
-        newInstrument(sf2, "Distorted Guitar", new Patch(0, 30), guitar_dist);
-        newInstrument(sf2, "Guitar", new Patch(0, 31), guitar, guitar_pick);
-        newInstrument(sf2, "Finger Bass", new Patch(0, 32), bass1);
-        newInstrument(sf2, "Finger Bass", new Patch(0, 33), bass1);
-        newInstrument(sf2, "Finger Bass", new Patch(0, 34), bass1);
-        newInstrument(sf2, "Frettless Bass", new Patch(0, 35), bass2);
-        newInstrument(sf2, "Frettless Bass", new Patch(0, 36), bass2);
-        newInstrument(sf2, "Frettless Bass", new Patch(0, 37), bass2);
-        newInstrument(sf2, "Synth Bass1", new Patch(0, 38), synthbass);
-        newInstrument(sf2, "Synth Bass2", new Patch(0, 39), synthbass);
-        newInstrument(sf2, "Solo String", new Patch(0, 40), string2, solostring);
-        newInstrument(sf2, "Solo String", new Patch(0, 41), string2, solostring);
-        newInstrument(sf2, "Solo String", new Patch(0, 42), string2, solostring);
-        newInstrument(sf2, "Solo String", new Patch(0, 43), string2, solostring);
-        newInstrument(sf2, "Solo String", new Patch(0, 44), string2, solostring);
-        newInstrument(sf2, "Def", new Patch(0, 45), defaultsound);
-        newInstrument(sf2, "Harp", new Patch(0, 46), bell);
-        newInstrument(sf2, "Timpani", new Patch(0, 47), timpani);
-        newInstrument(sf2, "Strings", new Patch(0, 48), string2);
-        SF2Instrument slow_strings =
-                newInstrument(sf2, "Slow Strings", new Patch(0, 49), string2);
-        SF2InstrumentRegion region = slow_strings.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, 2500);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 2000);
-        newInstrument(sf2, "Synth Strings", new Patch(0, 50), string2);
-        newInstrument(sf2, "Synth Strings", new Patch(0, 51), string2);
-
-
-        newInstrument(sf2, "Choir", new Patch(0, 52), choir);
-        newInstrument(sf2, "Choir", new Patch(0, 53), choir);
-        newInstrument(sf2, "Choir", new Patch(0, 54), choir);
-        {
-            SF2Instrument ins = newInstrument(sf2, "Orch Hit",
-                    new Patch(0, 55), orchhit, orchhit, timpani);
-            region = ins.getRegions().get(0);
-            region.putInteger(SF2Region.GENERATOR_COARSETUNE, -12);
-            region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        }
-        newInstrument(sf2, "Trumpet", new Patch(0, 56), trumpet);
-        newInstrument(sf2, "Trombone", new Patch(0, 57), trombone);
-        newInstrument(sf2, "Trombone", new Patch(0, 58), trombone);
-        newInstrument(sf2, "Trumpet", new Patch(0, 59), trumpet);
-        newInstrument(sf2, "Horn", new Patch(0, 60), horn);
-        newInstrument(sf2, "Brass Section", new Patch(0, 61), brass_section);
-        newInstrument(sf2, "Brass Section", new Patch(0, 62), brass_section);
-        newInstrument(sf2, "Brass Section", new Patch(0, 63), brass_section);
-        newInstrument(sf2, "Sax", new Patch(0, 64), sax);
-        newInstrument(sf2, "Sax", new Patch(0, 65), sax);
-        newInstrument(sf2, "Sax", new Patch(0, 66), sax);
-        newInstrument(sf2, "Sax", new Patch(0, 67), sax);
-        newInstrument(sf2, "Oboe", new Patch(0, 68), oboe);
-        newInstrument(sf2, "Horn", new Patch(0, 69), horn);
-        newInstrument(sf2, "Bassoon", new Patch(0, 70), bassoon);
-        newInstrument(sf2, "Clarinet", new Patch(0, 71), clarinet);
-        newInstrument(sf2, "Flute", new Patch(0, 72), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 73), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 74), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 75), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 76), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 77), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 78), flute);
-        newInstrument(sf2, "Flute", new Patch(0, 79), flute);
-        newInstrument(sf2, "Organ", new Patch(0, 80), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 81), organ);
-        newInstrument(sf2, "Flute", new Patch(0, 82), flute);
-        newInstrument(sf2, "Organ", new Patch(0, 83), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 84), organ);
-        newInstrument(sf2, "Choir", new Patch(0, 85), choir);
-        newInstrument(sf2, "Organ", new Patch(0, 86), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 87), organ);
-        newInstrument(sf2, "Synth Strings", new Patch(0, 88), string2);
-        newInstrument(sf2, "Organ", new Patch(0, 89), organ);
-        newInstrument(sf2, "Def", new Patch(0, 90), defaultsound);
-        newInstrument(sf2, "Choir", new Patch(0, 91), choir);
-        newInstrument(sf2, "Organ", new Patch(0, 92), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 93), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 94), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 95), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 96), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 97), organ);
-        newInstrument(sf2, "Bell", new Patch(0, 98), bell);
-        newInstrument(sf2, "Organ", new Patch(0, 99), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 100), organ);
-        newInstrument(sf2, "Organ", new Patch(0, 101), organ);
-        newInstrument(sf2, "Def", new Patch(0, 102), defaultsound);
-        newInstrument(sf2, "Synth Strings", new Patch(0, 103), string2);
-        newInstrument(sf2, "Def", new Patch(0, 104), defaultsound);
-        newInstrument(sf2, "Def", new Patch(0, 105), defaultsound);
-        newInstrument(sf2, "Def", new Patch(0, 106), defaultsound);
-        newInstrument(sf2, "Def", new Patch(0, 107), defaultsound);
-        newInstrument(sf2, "Marimba", new Patch(0, 108), bell);
-        newInstrument(sf2, "Sax", new Patch(0, 109), sax);
-        newInstrument(sf2, "Solo String", new Patch(0, 110), string2, solostring);
-        newInstrument(sf2, "Oboe", new Patch(0, 111), oboe);
-        newInstrument(sf2, "Bell", new Patch(0, 112), bell);
-        newInstrument(sf2, "Melodic Toms", new Patch(0, 113), melodic_toms);
-        newInstrument(sf2, "Marimba", new Patch(0, 114), bell);
-        newInstrument(sf2, "Melodic Toms", new Patch(0, 115), melodic_toms);
-        newInstrument(sf2, "Melodic Toms", new Patch(0, 116), melodic_toms);
-        newInstrument(sf2, "Melodic Toms", new Patch(0, 117), melodic_toms);
-        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 118), reverse_cymbal);
-        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 119), reverse_cymbal);
-        newInstrument(sf2, "Guitar", new Patch(0, 120), guitar);
-        newInstrument(sf2, "Def", new Patch(0, 121), defaultsound);
-        {
-            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
-                    new Patch(0, 122), reverse_cymbal);
-            region = ins.getRegions().get(0);
-            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
-            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
-            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
-        }
-        {
-            SF2Instrument ins = newInstrument(sf2, "Bird/Flute",
-                    new Patch(0, 123), flute);
-            region = ins.getRegions().get(0);
-            region.putInteger(SF2Region.GENERATOR_COARSETUNE, 24);
-            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -3000);
-            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        }
-        newInstrument(sf2, "Def", new Patch(0, 124), side_stick);
-        {
-            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
-                    new Patch(0, 125), reverse_cymbal);
-            region = ins.getRegions().get(0);
-            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
-            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
-            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
-        }
-        newInstrument(sf2, "Applause/crash_cymbal",
-                new Patch(0, 126), crash_cymbal);
-        newInstrument(sf2, "Gunshot/side_stick", new Patch(0, 127), side_stick);
-
-        for (SF2Instrument instrument : sf2.getInstruments()) {
-            Patch patch = instrument.getPatch();
-            if (patch instanceof ModelPatch) {
-                if (((ModelPatch) patch).isPercussion())
-                    continue;
-            }
-            instrument.setName(general_midi_instruments[patch.getProgram()]);
-        }
-
-        return sf2;
-
-    }
-
-    public static SF2Layer new_bell(SF2Soundbank sf2) {
-        Random random = new Random(102030201);
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.01;
-        double end_w = 0.05;
-        double start_a = 0.2;
-        double end_a = 0.00001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.01;
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1) * detune, w, a);
-            a *= a_step;
-        }
-        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
-        SF2Layer layer = newLayer(sf2, "EPiano", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
-        return layer;
-    }
-
-    public static SF2Layer new_guitar1(SF2Soundbank sf2) {
-
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.01;
-        double end_w = 0.01;
-        double start_a = 2;
-        double end_a = 0.01;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-
-        double[] aa = new double[40];
-        for (int i = 0; i < 40; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] = 2;
-        aa[1] = 0.5;
-        aa[2] = 0.45;
-        aa[3] = 0.2;
-        aa[4] = 1;
-        aa[5] = 0.5;
-        aa[6] = 2;
-        aa[7] = 1;
-        aa[8] = 0.5;
-        aa[9] = 1;
-        aa[9] = 0.5;
-        aa[10] = 0.2;
-        aa[11] = 1;
-        aa[12] = 0.7;
-        aa[13] = 0.5;
-        aa[14] = 1;
-
-        for (int i = 0; i < 40; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Guitar", data, base);
-        SF2Layer layer = newLayer(sf2, "Guitar", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -6000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
-        return layer;
-    }
-
-    public static SF2Layer new_guitar_dist(SF2Soundbank sf2) {
-
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.01;
-        double end_w = 0.01;
-        double start_a = 2;
-        double end_a = 0.01;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-
-        double[] aa = new double[40];
-        for (int i = 0; i < 40; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] = 5;
-        aa[1] = 2;
-        aa[2] = 0.45;
-        aa[3] = 0.2;
-        aa[4] = 1;
-        aa[5] = 0.5;
-        aa[6] = 2;
-        aa[7] = 1;
-        aa[8] = 0.5;
-        aa[9] = 1;
-        aa[9] = 0.5;
-        aa[10] = 0.2;
-        aa[11] = 1;
-        aa[12] = 0.7;
-        aa[13] = 0.5;
-        aa[14] = 1;
-
-        for (int i = 0; i < 40; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-        }
-
-
-        SF2Sample sample = newSimpleFFTSample_dist(sf2, "Distorted Guitar",
-                data, base, 10000.0);
-
-
-        SF2Layer layer = newLayer(sf2, "Distorted Guitar", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        //region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
-        //region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 200);
-
-        //region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
-        //region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        //region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -1000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
-        //region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
-        return layer;
-    }
-
-    public static SF2Layer new_guitar_pick(SF2Soundbank sf2) {
-
-        double datab[];
-
-        // Make treble part
-        {
-            int m = 2;
-            int fftlen = 4096 * m;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5));
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 0; i < 2048 * m; i++) {
-                data[i] *= Math.exp(-Math.abs((i - 23) / ((double) m)) * 1.2)
-                        + Math.exp(-Math.abs((i - 40) / ((double) m)) * 0.9);
-            }
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.8);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9994;
-            }
-            datab = data;
-
-            fadeUp(data, 80);
-        }
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Guitar Noise", datab);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Guitar Noise");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-//		region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-/*
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
-         */
-
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_gpiano(SF2Soundbank sf2) {
-        //Random random = new Random(302030201);
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 15.0);
-
-        double[] aa = new double[30];
-        for (int i = 0; i < 30; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 2;
-        //aa[2] *= 0.1;
-        aa[4] *= 2;
-
-
-        aa[12] *= 0.9;
-        aa[13] *= 0.7;
-        for (int i = 14; i < 30; i++) {
-            aa[i] *= 0.5;
-        }
-
-
-        for (int i = 0; i < 30; i++) {
-            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
-            double w = 0.2;
-            double ai = aa[i];
-            if (i > 10) {
-                w = 5;
-                ai *= 10;
-            }
-            int adjust = 0;
-            if (i > 5) {
-                adjust = (i - 5) * 7;
-            }
-            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
-        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
-        return layer;
-    }
-
-    public static SF2Layer new_gpiano2(SF2Soundbank sf2) {
-        //Random random = new Random(302030201);
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 20.0);
-
-        double[] aa = new double[30];
-        for (int i = 0; i < 30; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 1;
-        //aa[2] *= 0.1;
-        aa[4] *= 2;
-
-
-        aa[12] *= 0.9;
-        aa[13] *= 0.7;
-        for (int i = 14; i < 30; i++) {
-            aa[i] *= 0.5;
-        }
-
-
-        for (int i = 0; i < 30; i++) {
-            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
-            double w = 0.2;
-            double ai = aa[i];
-            if (i > 10) {
-                w = 5;
-                ai *= 10;
-            }
-            int adjust = 0;
-            if (i > 5) {
-                adjust = (i - 5) * 7;
-            }
-            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
-        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
-        return layer;
-    }
-
-    public static SF2Layer new_piano_hammer(SF2Soundbank sf2) {
-
-        double datab[];
-
-        // Make treble part
-        {
-            int m = 2;
-            int fftlen = 4096 * m;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5));
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 0; i < 2048 * m; i++)
-                data[i] *= Math.exp(-Math.abs((i - 37) / ((double) m)) * 0.05);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.6);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9997;
-            }
-            datab = data;
-
-            fadeUp(data, 80);
-        }
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Piano Hammer", datab);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Piano Hammer");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-/*
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
-         */
-
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_piano1(SF2Soundbank sf2) {
-        //Random random = new Random(302030201);
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_a = 0.2;
-        double end_a = 0.0001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-
-        double[] aa = new double[30];
-        for (int i = 0; i < 30; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 5;
-        aa[2] *= 0.1;
-        aa[7] *= 5;
-
-
-        for (int i = 0; i < 30; i++) {
-            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
-            double w = 0.2;
-            double ai = aa[i];
-            if (i > 12) {
-                w = 5;
-                ai *= 10;
-            }
-            int adjust = 0;
-            if (i > 5) {
-                adjust = (i - 5) * 7;
-            }
-            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
-        }
-
-        complexGaussianDist(data, base * (15.5), 1, 0.1);
-        complexGaussianDist(data, base * (17.5), 1, 0.01);
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base, 200);
-        SF2Layer layer = newLayer(sf2, "EPiano", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -1200);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
-        return layer;
-    }
-
-    public static SF2Layer new_epiano1(SF2Soundbank sf2) {
-        Random random = new Random(302030201);
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.05;
-        double end_w = 0.05;
-        double start_a = 0.2;
-        double end_a = 0.0001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1) * detune, w, a);
-            a *= a_step;
-        }
-
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
-        SF2Layer layer = newLayer(sf2, "EPiano", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
-        return layer;
-    }
-
-    public static SF2Layer new_epiano2(SF2Soundbank sf2) {
-        Random random = new Random(302030201);
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.01;
-        double end_w = 0.05;
-        double start_a = 0.2;
-        double end_a = 0.00001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1) * detune, w, a);
-            a *= a_step;
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
-        SF2Layer layer = newLayer(sf2, "EPiano", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 8000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 2400);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        return layer;
-    }
-
-    public static SF2Layer new_bass1(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.05;
-        double end_w = 0.05;
-        double start_a = 0.2;
-        double end_a = 0.02;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
-
-        double[] aa = new double[25];
-        for (int i = 0; i < 25; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 8;
-        aa[1] *= 4;
-        aa[3] *= 8;
-        aa[5] *= 8;
-
-        for (int i = 0; i < 25; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-        }
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
-        SF2Layer layer = newLayer(sf2, "Bass", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 11000);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        return layer;
-    }
-
-    public static SF2Layer new_synthbass(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.05;
-        double end_w = 0.05;
-        double start_a = 0.2;
-        double end_a = 0.02;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
-
-        double[] aa = new double[25];
-        for (int i = 0; i < 25; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 16;
-        aa[1] *= 4;
-        aa[3] *= 16;
-        aa[5] *= 8;
-
-        for (int i = 0; i < 25; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-        }
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
-        SF2Layer layer = newLayer(sf2, "Bass", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -3000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        return layer;
-    }
-
-    public static SF2Layer new_bass2(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 0.05;
-        double end_w = 0.05;
-        double start_a = 0.2;
-        double end_a = 0.002;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
-
-        double[] aa = new double[25];
-        for (int i = 0; i < 25; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 8;
-        aa[1] *= 4;
-        aa[3] *= 8;
-        aa[5] *= 8;
-
-        for (int i = 0; i < 25; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-        }
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Bass2", data, base);
-        SF2Layer layer = newLayer(sf2, "Bass2", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        return layer;
-    }
-
-    public static SF2Layer new_solostring(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 2;
-        double end_w = 2;
-        double start_a = 0.2;
-        double end_a = 0.01;
-
-        double[] aa = new double[18];
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < aa.length; i++) {
-            a *= a_step;
-            aa[i] = a;
-        }
-
-        aa[0] *= 5;
-        aa[1] *= 5;
-        aa[2] *= 5;
-        aa[3] *= 4;
-        aa[4] *= 4;
-        aa[5] *= 3;
-        aa[6] *= 3;
-        aa[7] *= 2;
-
-        for (int i = 0; i < aa.length; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, a);
-        }
-        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
-        SF2Layer layer = newLayer(sf2, "Strings", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        region.putInteger(SF2Region.GENERATOR_FREQVIBLFO, -1000);
-        region.putInteger(SF2Region.GENERATOR_VIBLFOTOPITCH, 15);
-        return layer;
-
-    }
-
-    public static SF2Layer new_orchhit(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 2;
-        double end_w = 80;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, a);
-            a *= a_step;
-        }
-        complexGaussianDist(data, base * 4, 300, 1);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Och Strings", data, base);
-        SF2Layer layer = newLayer(sf2, "Och Strings", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 200);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 200);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_string2(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 2;
-        double end_w = 80;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, a);
-            a *= a_step;
-        }
-        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
-        SF2Layer layer = newLayer(sf2, "Strings", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_choir(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 25;
-        double start_w = 2;
-        double end_w = 80;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        double[] aa = new double[40];
-        for (int i = 0; i < aa.length; i++) {
-            a *= a_step;
-            aa[i] = a;
-        }
-
-        aa[5] *= 0.1;
-        aa[6] *= 0.01;
-        aa[7] *= 0.1;
-        aa[8] *= 0.1;
-
-        for (int i = 0; i < aa.length; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-        }
-        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
-        SF2Layer layer = newLayer(sf2, "Strings", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_organ(SF2Soundbank sf2) {
-        Random random = new Random(102030201);
-        int x = 1;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-        double start_w = 0.01;
-        double end_w = 0.01;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-
-        for (int i = 0; i < 12; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w,
-                    a * (0.5 + 3 * (random.nextDouble())));
-            a *= a_step;
-        }
-        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
-        SF2Layer layer = newLayer(sf2, "Organ", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_ch_organ(SF2Soundbank sf2) {
-        int x = 1;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-        double start_w = 0.01;
-        double end_w = 0.01;
-        double start_a = 0.2;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 60.0);
-
-        double[] aa = new double[60];
-        for (int i = 0; i < aa.length; i++) {
-            a *= a_step;
-            aa[i] = a;
-        }
-
-        aa[0] *= 5;
-        aa[1] *= 2;
-        aa[2] = 0;
-        aa[4] = 0;
-        aa[5] = 0;
-        aa[7] *= 7;
-        aa[9] = 0;
-        aa[10] = 0;
-        aa[12] = 0;
-        aa[15] *= 7;
-        aa[18] = 0;
-        aa[20] = 0;
-        aa[24] = 0;
-        aa[27] *= 5;
-        aa[29] = 0;
-        aa[30] = 0;
-        aa[33] = 0;
-        aa[36] *= 4;
-        aa[37] = 0;
-        aa[39] = 0;
-        aa[42] = 0;
-        aa[43] = 0;
-        aa[47] = 0;
-        aa[50] *= 4;
-        aa[52] = 0;
-        aa[55] = 0;
-        aa[57] = 0;
-
-
-        aa[10] *= 0.1;
-        aa[11] *= 0.1;
-        aa[12] *= 0.1;
-        aa[13] *= 0.1;
-
-        aa[17] *= 0.1;
-        aa[18] *= 0.1;
-        aa[19] *= 0.1;
-        aa[20] *= 0.1;
-
-        for (int i = 0; i < 60; i++) {
-            double w = start_w + (end_w - start_w) * (i / 40.0);
-            complexGaussianDist(data, base * (i + 1), w, aa[i]);
-            a *= a_step;
-        }
-        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
-        SF2Layer layer = newLayer(sf2, "Organ", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        return layer;
-
-    }
-
-    public static SF2Layer new_flute(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        complexGaussianDist(data, base * 1, 0.001, 0.5);
-        complexGaussianDist(data, base * 2, 0.001, 0.5);
-        complexGaussianDist(data, base * 3, 0.001, 0.5);
-        complexGaussianDist(data, base * 4, 0.01, 0.5);
-
-        complexGaussianDist(data, base * 4, 100, 120);
-        complexGaussianDist(data, base * 6, 100, 40);
-        complexGaussianDist(data, base * 8, 100, 80);
-
-        complexGaussianDist(data, base * 5, 0.001, 0.05);
-        complexGaussianDist(data, base * 6, 0.001, 0.06);
-        complexGaussianDist(data, base * 7, 0.001, 0.04);
-        complexGaussianDist(data, base * 8, 0.005, 0.06);
-        complexGaussianDist(data, base * 9, 0.005, 0.06);
-        complexGaussianDist(data, base * 10, 0.01, 0.1);
-        complexGaussianDist(data, base * 11, 0.08, 0.7);
-        complexGaussianDist(data, base * 12, 0.08, 0.6);
-        complexGaussianDist(data, base * 13, 0.08, 0.6);
-        complexGaussianDist(data, base * 14, 0.08, 0.6);
-        complexGaussianDist(data, base * 15, 0.08, 0.5);
-        complexGaussianDist(data, base * 16, 0.08, 0.5);
-        complexGaussianDist(data, base * 17, 0.08, 0.2);
-
-
-        complexGaussianDist(data, base * 1, 10, 8);
-        complexGaussianDist(data, base * 2, 10, 8);
-        complexGaussianDist(data, base * 3, 10, 8);
-        complexGaussianDist(data, base * 4, 10, 8);
-        complexGaussianDist(data, base * 5, 10, 8);
-        complexGaussianDist(data, base * 6, 20, 9);
-        complexGaussianDist(data, base * 7, 20, 9);
-        complexGaussianDist(data, base * 8, 20, 9);
-        complexGaussianDist(data, base * 9, 20, 8);
-        complexGaussianDist(data, base * 10, 30, 8);
-        complexGaussianDist(data, base * 11, 30, 9);
-        complexGaussianDist(data, base * 12, 30, 9);
-        complexGaussianDist(data, base * 13, 30, 8);
-        complexGaussianDist(data, base * 14, 30, 8);
-        complexGaussianDist(data, base * 15, 30, 7);
-        complexGaussianDist(data, base * 16, 30, 7);
-        complexGaussianDist(data, base * 17, 30, 6);
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
-        SF2Layer layer = newLayer(sf2, "Flute", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_horn(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        double start_a = 0.5;
-        double end_a = 0.00000000001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            if (i == 0)
-                complexGaussianDist(data, base * (i + 1), 0.1, a * 0.2);
-            else
-                complexGaussianDist(data, base * (i + 1), 0.1, a);
-            a *= a_step;
-        }
-
-        complexGaussianDist(data, base * 2, 100, 1);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Horn", data, base);
-        SF2Layer layer = newLayer(sf2, "Horn", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -500);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_trumpet(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        double start_a = 0.5;
-        double end_a = 0.00001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
-        double[] aa = new double[80];
-        for (int i = 0; i < 80; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 0.05;
-        aa[1] *= 0.2;
-        aa[2] *= 0.5;
-        aa[3] *= 0.85;
-
-        for (int i = 0; i < 80; i++) {
-            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
-        }
-
-        complexGaussianDist(data, base * 5, 300, 3);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Trumpet", data, base);
-        SF2Layer layer = newLayer(sf2, "Trumpet", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -4000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, -2500);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
-        return layer;
-
-    }
-
-    public static SF2Layer new_brass_section(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        double start_a = 0.5;
-        double end_a = 0.005;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 30.0);
-        double[] aa = new double[30];
-        for (int i = 0; i < 30; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 0.8;
-        aa[1] *= 0.9;
-
-        double w = 5;
-        for (int i = 0; i < 30; i++) {
-            complexGaussianDist(data, base * (i + 1), 0.1 * w, aa[i] * w);
-            w += 6; //*= w_step;
-        }
-
-        complexGaussianDist(data, base * 6, 300, 2);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Brass Section", data, base);
-        SF2Layer layer = newLayer(sf2, "Brass Section", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -9200);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_trombone(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        double start_a = 0.5;
-        double end_a = 0.001;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
-        double[] aa = new double[80];
-        for (int i = 0; i < 80; i++) {
-            aa[i] = a;
-            a *= a_step;
-        }
-
-        aa[0] *= 0.3;
-        aa[1] *= 0.7;
-
-        for (int i = 0; i < 80; i++) {
-            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
-        }
-
-        complexGaussianDist(data, base * 6, 300, 2);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Trombone", data, base);
-        SF2Layer layer = newLayer(sf2, "Trombone", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -2000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
-        return layer;
-
-    }
-
-    public static SF2Layer new_sax(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        double start_a = 0.5;
-        double end_a = 0.01;
-        double a = start_a;
-        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
-        for (int i = 0; i < 40; i++) {
-            if (i == 0 || i == 2)
-                complexGaussianDist(data, base * (i + 1), 0.1, a * 4);
-            else
-                complexGaussianDist(data, base * (i + 1), 0.1, a);
-            a *= a_step;
-        }
-
-        complexGaussianDist(data, base * 4, 200, 1);
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Sax", data, base);
-        SF2Layer layer = newLayer(sf2, "Sax", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-
-        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_oboe(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        complexGaussianDist(data, base * 5, 100, 80);
-
-
-        complexGaussianDist(data, base * 1, 0.01, 0.53);
-        complexGaussianDist(data, base * 2, 0.01, 0.51);
-        complexGaussianDist(data, base * 3, 0.01, 0.48);
-        complexGaussianDist(data, base * 4, 0.01, 0.49);
-        complexGaussianDist(data, base * 5, 0.01, 5);
-        complexGaussianDist(data, base * 6, 0.01, 0.51);
-        complexGaussianDist(data, base * 7, 0.01, 0.50);
-        complexGaussianDist(data, base * 8, 0.01, 0.59);
-        complexGaussianDist(data, base * 9, 0.01, 0.61);
-        complexGaussianDist(data, base * 10, 0.01, 0.52);
-        complexGaussianDist(data, base * 11, 0.01, 0.49);
-        complexGaussianDist(data, base * 12, 0.01, 0.51);
-        complexGaussianDist(data, base * 13, 0.01, 0.48);
-        complexGaussianDist(data, base * 14, 0.01, 0.51);
-        complexGaussianDist(data, base * 15, 0.01, 0.46);
-        complexGaussianDist(data, base * 16, 0.01, 0.35);
-        complexGaussianDist(data, base * 17, 0.01, 0.20);
-        complexGaussianDist(data, base * 18, 0.01, 0.10);
-        complexGaussianDist(data, base * 19, 0.01, 0.5);
-        complexGaussianDist(data, base * 20, 0.01, 0.1);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Oboe", data, base);
-        SF2Layer layer = newLayer(sf2, "Oboe", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_bassoon(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        complexGaussianDist(data, base * 2, 100, 40);
-        complexGaussianDist(data, base * 4, 100, 20);
-
-        complexGaussianDist(data, base * 1, 0.01, 0.53);
-        complexGaussianDist(data, base * 2, 0.01, 5);
-        complexGaussianDist(data, base * 3, 0.01, 0.51);
-        complexGaussianDist(data, base * 4, 0.01, 0.48);
-        complexGaussianDist(data, base * 5, 0.01, 1.49);
-        complexGaussianDist(data, base * 6, 0.01, 0.51);
-        complexGaussianDist(data, base * 7, 0.01, 0.50);
-        complexGaussianDist(data, base * 8, 0.01, 0.59);
-        complexGaussianDist(data, base * 9, 0.01, 0.61);
-        complexGaussianDist(data, base * 10, 0.01, 0.52);
-        complexGaussianDist(data, base * 11, 0.01, 0.49);
-        complexGaussianDist(data, base * 12, 0.01, 0.51);
-        complexGaussianDist(data, base * 13, 0.01, 0.48);
-        complexGaussianDist(data, base * 14, 0.01, 0.51);
-        complexGaussianDist(data, base * 15, 0.01, 0.46);
-        complexGaussianDist(data, base * 16, 0.01, 0.35);
-        complexGaussianDist(data, base * 17, 0.01, 0.20);
-        complexGaussianDist(data, base * 18, 0.01, 0.10);
-        complexGaussianDist(data, base * 19, 0.01, 0.5);
-        complexGaussianDist(data, base * 20, 0.01, 0.1);
-
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
-        SF2Layer layer = newLayer(sf2, "Flute", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_clarinet(SF2Soundbank sf2) {
-        int x = 8;
-        int fftsize = 4096 * x;
-        double[] data = new double[fftsize * 2];
-        double base = x * 15;
-
-        complexGaussianDist(data, base * 1, 0.001, 0.5);
-        complexGaussianDist(data, base * 2, 0.001, 0.02);
-        complexGaussianDist(data, base * 3, 0.001, 0.2);
-        complexGaussianDist(data, base * 4, 0.01, 0.1);
-
-        complexGaussianDist(data, base * 4, 100, 60);
-        complexGaussianDist(data, base * 6, 100, 20);
-        complexGaussianDist(data, base * 8, 100, 20);
-
-        complexGaussianDist(data, base * 5, 0.001, 0.1);
-        complexGaussianDist(data, base * 6, 0.001, 0.09);
-        complexGaussianDist(data, base * 7, 0.001, 0.02);
-        complexGaussianDist(data, base * 8, 0.005, 0.16);
-        complexGaussianDist(data, base * 9, 0.005, 0.96);
-        complexGaussianDist(data, base * 10, 0.01, 0.9);
-        complexGaussianDist(data, base * 11, 0.08, 1.2);
-        complexGaussianDist(data, base * 12, 0.08, 1.8);
-        complexGaussianDist(data, base * 13, 0.08, 1.6);
-        complexGaussianDist(data, base * 14, 0.08, 1.2);
-        complexGaussianDist(data, base * 15, 0.08, 0.9);
-        complexGaussianDist(data, base * 16, 0.08, 0.5);
-        complexGaussianDist(data, base * 17, 0.08, 0.2);
-
-
-        complexGaussianDist(data, base * 1, 10, 8);
-        complexGaussianDist(data, base * 2, 10, 8);
-        complexGaussianDist(data, base * 3, 10, 8);
-        complexGaussianDist(data, base * 4, 10, 8);
-        complexGaussianDist(data, base * 5, 10, 8);
-        complexGaussianDist(data, base * 6, 20, 9);
-        complexGaussianDist(data, base * 7, 20, 9);
-        complexGaussianDist(data, base * 8, 20, 9);
-        complexGaussianDist(data, base * 9, 20, 8);
-        complexGaussianDist(data, base * 10, 30, 8);
-        complexGaussianDist(data, base * 11, 30, 9);
-        complexGaussianDist(data, base * 12, 30, 9);
-        complexGaussianDist(data, base * 13, 30, 8);
-        complexGaussianDist(data, base * 14, 30, 8);
-        complexGaussianDist(data, base * 15, 30, 7);
-        complexGaussianDist(data, base * 16, 30, 7);
-        complexGaussianDist(data, base * 17, 30, 6);
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Clarinet", data, base);
-        SF2Layer layer = newLayer(sf2, "Clarinet", sample);
-        SF2Region region = layer.getRegions().get(0);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
-        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
-        return layer;
-
-    }
-
-    public static SF2Layer new_timpani(SF2Soundbank sf2) {
-
-        double datab[];
-        double datah[];
-
-        // Make Bass Part
-        {
-            int fftlen = 4096 * 8;
-            double[] data = new double[2 * fftlen];
-            double base = 48;
-            complexGaussianDist(data, base * 2, 0.2, 1);
-            complexGaussianDist(data, base * 3, 0.2, 0.7);
-            complexGaussianDist(data, base * 5, 10, 1);
-            complexGaussianDist(data, base * 6, 9, 1);
-            complexGaussianDist(data, base * 8, 15, 1);
-            complexGaussianDist(data, base * 9, 18, 0.8);
-            complexGaussianDist(data, base * 11, 21, 0.5);
-            complexGaussianDist(data, base * 13, 28, 0.3);
-            complexGaussianDist(data, base * 14, 22, 0.1);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.5);
-            data = realPart(data);
-
-            double d_len = data.length;
-            for (int i = 0; i < data.length; i++) {
-                double g = (1.0 - (i / d_len));
-                data[i] *= g * g;
-            }
-            fadeUp(data, 40);
-            datab = data;
-        }
-
-        // Make treble part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2) {
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            }
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024 * 4; i < 2048 * 4; i++)
-                data[i] = 1.0 - (i - 4096) / 4096.0;
-            for (int i = 0; i < 300; i++) {
-                double g = (1.0 - (i / 300.0));
-                data[i] *= 1.0 + 20 * g * g;
-            }
-            for (int i = 0; i < 24; i++)
-                data[i] = 0;
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9998;
-            }
-            datah = data;
-        }
-
-        for (int i = 0; i < datah.length; i++)
-            datab[i] += datah[i] * 0.02;
-
-        normalize(datab, 0.9);
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Timpani", datab);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Timpani");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_melodic_toms(SF2Soundbank sf2) {
-
-        double datab[];
-        double datah[];
-
-        // Make Bass Part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            complexGaussianDist(data, 30, 0.5, 1);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.8);
-            data = realPart(data);
-
-            double d_len = data.length;
-            for (int i = 0; i < data.length; i++)
-                data[i] *= (1.0 - (i / d_len));
-            datab = data;
-        }
-
-        // Make treble part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024 * 4; i < 2048 * 4; i++)
-                data[i] = 1.0 - (i - 4096) / 4096.0;
-            for (int i = 0; i < 200; i++) {
-                double g = (1.0 - (i / 200.0));
-                data[i] *= 1.0 + 20 * g * g;
-            }
-            for (int i = 0; i < 30; i++)
-                data[i] = 0;
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9996;
-            }
-            datah = data;
-        }
-
-        for (int i = 0; i < datah.length; i++)
-            datab[i] += datah[i] * 0.5;
-        for (int i = 0; i < 5; i++)
-            datab[i] *= i / 5.0;
-
-        normalize(datab, 0.99);
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Melodic Toms", datab);
-        sample.setOriginalPitch(63);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Melodic Toms");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_reverse_cymbal(SF2Soundbank sf2) {
-        double datah[];
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5));
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 0; i < 100; i++)
-                data[i] = 0;
-
-            for (int i = 0; i < 512 * 2; i++) {
-                double gain = (i / (512.0 * 2.0));
-                data[i] = 1 - gain;
-            }
-            datah = data;
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Reverse Cymbal",
-                datah, 100, 20);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Reverse Cymbal");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -200);
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -12000);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_snare_drum(SF2Soundbank sf2) {
-
-        double datab[];
-        double datah[];
-
-        // Make Bass Part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            complexGaussianDist(data, 24, 0.5, 1);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.5);
-            data = realPart(data);
-
-            double d_len = data.length;
-            for (int i = 0; i < data.length; i++)
-                data[i] *= (1.0 - (i / d_len));
-            datab = data;
-        }
-
-        // Make treble part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024 * 4; i < 2048 * 4; i++)
-                data[i] = 1.0 - (i - 4096) / 4096.0;
-            for (int i = 0; i < 300; i++) {
-                double g = (1.0 - (i / 300.0));
-                data[i] *= 1.0 + 20 * g * g;
-            }
-            for (int i = 0; i < 24; i++)
-                data[i] = 0;
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9998;
-            }
-            datah = data;
-        }
-
-        for (int i = 0; i < datah.length; i++)
-            datab[i] += datah[i];
-        for (int i = 0; i < 5; i++)
-            datab[i] *= i / 5.0;
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Snare Drum", datab);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Snare Drum");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_bass_drum(SF2Soundbank sf2) {
-
-        double datab[];
-        double datah[];
-
-        // Make Bass Part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            complexGaussianDist(data, 1.8 * 5 + 1, 2, 1);
-            complexGaussianDist(data, 1.8 * 9 + 1, 2, 1);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double d_len = data.length;
-            for (int i = 0; i < data.length; i++)
-                data[i] *= (1.0 - (i / d_len));
-            datab = data;
-        }
-
-        // Make treble part
-        {
-            int fftlen = 4096;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024; i < 2048; i++)
-                data[i] = 1.0 - (i - 1024) / 1024.0;
-            for (int i = 0; i < 512; i++)
-                data[i] = 10 * i / 512.0;
-            for (int i = 0; i < 10; i++)
-                data[i] = 0;
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.999;
-            }
-            datah = data;
-        }
-
-        for (int i = 0; i < datah.length; i++)
-            datab[i] += datah[i] * 0.5;
-        for (int i = 0; i < 5; i++)
-            datab[i] *= i / 5.0;
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Bass Drum", datab);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Bass Drum");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_tom(SF2Soundbank sf2) {
-
-        double datab[];
-        double datah[];
-
-        // Make Bass Part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            complexGaussianDist(data, 30, 0.5, 1);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.8);
-            data = realPart(data);
-
-            double d_len = data.length;
-            for (int i = 0; i < data.length; i++)
-                data[i] *= (1.0 - (i / d_len));
-            datab = data;
-        }
-
-        // Make treble part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024 * 4; i < 2048 * 4; i++)
-                data[i] = 1.0 - (i - 4096) / 4096.0;
-            for (int i = 0; i < 200; i++) {
-                double g = (1.0 - (i / 200.0));
-                data[i] *= 1.0 + 20 * g * g;
-            }
-            for (int i = 0; i < 30; i++)
-                data[i] = 0;
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9996;
-            }
-            datah = data;
-        }
-
-        for (int i = 0; i < datah.length; i++)
-            datab[i] += datah[i] * 0.5;
-        for (int i = 0; i < 5; i++)
-            datab[i] *= i / 5.0;
-
-        normalize(datab, 0.99);
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Tom", datab);
-        sample.setOriginalPitch(50);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Tom");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_closed_hihat(SF2Soundbank sf2) {
-        double datah[];
-
-        // Make treble part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024 * 4; i < 2048 * 4; i++)
-                data[i] = 1.0 - (i - 4096) / 4096.0;
-            for (int i = 0; i < 2048; i++)
-                data[i] = 0.2 + 0.8 * (i / 2048.0);
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9996;
-            }
-            datah = data;
-        }
-
-        for (int i = 0; i < 5; i++)
-            datah[i] *= i / 5.0;
-        SF2Sample sample = newSimpleDrumSample(sf2, "Closed Hi-Hat", datah);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Closed Hi-Hat");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_open_hihat(SF2Soundbank sf2) {
-        double datah[];
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5));
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 0; i < 200; i++)
-                data[i] = 0;
-            for (int i = 0; i < 2048 * 4; i++) {
-                double gain = (i / (2048.0 * 4.0));
-                data[i] = gain;
-            }
-            datah = data;
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Open Hi-Hat", datah, 1000, 5);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Open Hi-Hat");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1500);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1500);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_crash_cymbal(SF2Soundbank sf2) {
-        double datah[];
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5));
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 0; i < 100; i++)
-                data[i] = 0;
-            for (int i = 0; i < 512 * 2; i++) {
-                double gain = (i / (512.0 * 2.0));
-                data[i] = gain;
-            }
-            datah = data;
-        }
-
-        SF2Sample sample = newSimpleFFTSample(sf2, "Crash Cymbal", datah, 1000, 5);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Crash Cymbal");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1800);
-        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1800);
-        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
-        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-    }
-
-    public static SF2Layer new_side_stick(SF2Soundbank sf2) {
-        double datab[];
-
-        // Make treble part
-        {
-            int fftlen = 4096 * 4;
-            double[] data = new double[2 * fftlen];
-            Random random = new Random(3049912);
-            for (int i = 0; i < data.length; i += 2)
-                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
-            fft(data);
-            // Remove all negative frequency
-            for (int i = fftlen / 2; i < data.length; i++)
-                data[i] = 0;
-            for (int i = 1024 * 4; i < 2048 * 4; i++)
-                data[i] = 1.0 - (i - 4096) / 4096.0;
-            for (int i = 0; i < 200; i++) {
-                double g = (1.0 - (i / 200.0));
-                data[i] *= 1.0 + 20 * g * g;
-            }
-            for (int i = 0; i < 30; i++)
-                data[i] = 0;
-            randomPhase(data, new Random(3049912));
-            ifft(data);
-            normalize(data, 0.9);
-            data = realPart(data);
-            double gain = 1.0;
-            for (int i = 0; i < data.length; i++) {
-                data[i] *= gain;
-                gain *= 0.9996;
-            }
-            datab = data;
-        }
-
-        for (int i = 0; i < 10; i++)
-            datab[i] *= i / 10.0;
-
-        SF2Sample sample = newSimpleDrumSample(sf2, "Side Stick", datab);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName("Side Stick");
-
-        SF2GlobalRegion global = new SF2GlobalRegion();
-        layer.setGlobalZone(global);
-        sf2.addResource(layer);
-
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
-        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
-        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -50);
-        region.setSample(sample);
-        layer.getRegions().add(region);
-
-        return layer;
-
-    }
-
-    public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name,
-            double[] data, double base) {
-        return newSimpleFFTSample(sf2, name, data, base, 10);
-    }
-
-    public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name,
-            double[] data, double base, int fadeuptime) {
-
-        int fftsize = data.length / 2;
-        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
-        double basefreq = (base / fftsize) * format.getSampleRate() * 0.5;
-
-        randomPhase(data);
-        ifft(data);
-        data = realPart(data);
-        normalize(data, 0.9);
-        float[] fdata = toFloat(data);
-        fdata = loopExtend(fdata, fdata.length + 512);
-        fadeUp(fdata, fadeuptime);
-        byte[] bdata = toBytes(fdata, format);
-
-        /*
-         * Create SoundFont2 sample.
-         */
-        SF2Sample sample = new SF2Sample(sf2);
-        sample.setName(name);
-        sample.setData(bdata);
-        sample.setStartLoop(256);
-        sample.setEndLoop(fftsize + 256);
-        sample.setSampleRate((long) format.getSampleRate());
-        double orgnote = (69 + 12)
-                + (12 * Math.log(basefreq / 440.0) / Math.log(2));
-        sample.setOriginalPitch((int) orgnote);
-        sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0));
-        sf2.addResource(sample);
-
-        return sample;
-    }
-
-    public static SF2Sample newSimpleFFTSample_dist(SF2Soundbank sf2,
-            String name, double[] data, double base, double preamp) {
-
-        int fftsize = data.length / 2;
-        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
-        double basefreq = (base / fftsize) * format.getSampleRate() * 0.5;
-
-        randomPhase(data);
-        ifft(data);
-        data = realPart(data);
-
-        for (int i = 0; i < data.length; i++) {
-            data[i] = (1 - Math.exp(-Math.abs(data[i] * preamp)))
-                    * Math.signum(data[i]);
-        }
-
-        normalize(data, 0.9);
-        float[] fdata = toFloat(data);
-        fdata = loopExtend(fdata, fdata.length + 512);
-        fadeUp(fdata, 80);
-        byte[] bdata = toBytes(fdata, format);
-
-        /*
-         * Create SoundFont2 sample.
-         */
-        SF2Sample sample = new SF2Sample(sf2);
-        sample.setName(name);
-        sample.setData(bdata);
-        sample.setStartLoop(256);
-        sample.setEndLoop(fftsize + 256);
-        sample.setSampleRate((long) format.getSampleRate());
-        double orgnote = (69 + 12)
-                + (12 * Math.log(basefreq / 440.0) / Math.log(2));
-        sample.setOriginalPitch((int) orgnote);
-        sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0));
-        sf2.addResource(sample);
-
-        return sample;
-    }
-
-    public static SF2Sample newSimpleDrumSample(SF2Soundbank sf2, String name,
-            double[] data) {
-
-        int fftsize = data.length;
-        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
-
-        byte[] bdata = toBytes(toFloat(realPart(data)), format);
-
-        /*
-         * Create SoundFont2 sample.
-         */
-        SF2Sample sample = new SF2Sample(sf2);
-        sample.setName(name);
-        sample.setData(bdata);
-        sample.setStartLoop(256);
-        sample.setEndLoop(fftsize + 256);
-        sample.setSampleRate((long) format.getSampleRate());
-        sample.setOriginalPitch(60);
-        sf2.addResource(sample);
-
-        return sample;
-    }
-
-    public static SF2Layer newLayer(SF2Soundbank sf2, String name, SF2Sample sample) {
-        SF2LayerRegion region = new SF2LayerRegion();
-        region.setSample(sample);
-
-        SF2Layer layer = new SF2Layer(sf2);
-        layer.setName(name);
-        layer.getRegions().add(region);
-        sf2.addResource(layer);
-
-        return layer;
-    }
-
-    public static SF2Instrument newInstrument(SF2Soundbank sf2, String name,
-            Patch patch, SF2Layer... layers) {
-
-        /*
-         * Create SoundFont2 instrument.
-         */
-        SF2Instrument ins = new SF2Instrument(sf2);
-        ins.setPatch(patch);
-        ins.setName(name);
-        sf2.addInstrument(ins);
-
-        /*
-         * Create region for instrument.
-         */
-        for (int i = 0; i < layers.length; i++) {
-            SF2InstrumentRegion insregion = new SF2InstrumentRegion();
-            insregion.setLayer(layers[i]);
-            ins.getRegions().add(insregion);
-        }
-
-        return ins;
-    }
-
-    static public void ifft(double[] data) {
-        new FFT(data.length / 2, 1).transform(data);
-    }
-
-    static public void fft(double[] data) {
-        new FFT(data.length / 2, -1).transform(data);
-    }
-
-    public static void complexGaussianDist(double[] cdata, double m,
-            double s, double v) {
-        for (int x = 0; x < cdata.length / 4; x++) {
-            cdata[x * 2] += v * (1.0 / (s * Math.sqrt(2 * Math.PI))
-                    * Math.exp((-1.0 / 2.0) * Math.pow((x - m) / s, 2.0)));
-        }
-    }
-
-    static public void randomPhase(double[] data) {
-        for (int i = 0; i < data.length; i += 2) {
-            double phase = Math.random() * 2 * Math.PI;
-            double d = data[i];
-            data[i] = Math.sin(phase) * d;
-            data[i + 1] = Math.cos(phase) * d;
-        }
-    }
-
-    static public void randomPhase(double[] data, Random random) {
-        for (int i = 0; i < data.length; i += 2) {
-            double phase = random.nextDouble() * 2 * Math.PI;
-            double d = data[i];
-            data[i] = Math.sin(phase) * d;
-            data[i + 1] = Math.cos(phase) * d;
-        }
-    }
-
-    static public void normalize(double[] data, double target) {
-        double maxvalue = 0;
-        for (int i = 0; i < data.length; i++) {
-            if (data[i] > maxvalue)
-                maxvalue = data[i];
-            if (-data[i] > maxvalue)
-                maxvalue = -data[i];
-        }
-        if (maxvalue == 0)
-            return;
-        double gain = target / maxvalue;
-        for (int i = 0; i < data.length; i++)
-            data[i] *= gain;
-    }
-
-    static public void normalize(float[] data, double target) {
-        double maxvalue = 0.5;
-        for (int i = 0; i < data.length; i++) {
-            if (data[i * 2] > maxvalue)
-                maxvalue = data[i * 2];
-            if (-data[i * 2] > maxvalue)
-                maxvalue = -data[i * 2];
-        }
-        double gain = target / maxvalue;
-        for (int i = 0; i < data.length; i++)
-            data[i * 2] *= gain;
-    }
-
-    static public double[] realPart(double[] in) {
-        double[] out = new double[in.length / 2];
-        for (int i = 0; i < out.length; i++) {
-            out[i] = in[i * 2];
-        }
-        return out;
-    }
-
-    static public double[] imgPart(double[] in) {
-        double[] out = new double[in.length / 2];
-        for (int i = 0; i < out.length; i++) {
-            out[i] = in[i * 2];
-        }
-        return out;
-    }
-
-    static public float[] toFloat(double[] in) {
-        float[] out = new float[in.length];
-        for (int i = 0; i < out.length; i++) {
-            out[i] = (float) in[i];
-        }
-        return out;
-    }
-
-    static public byte[] toBytes(float[] in, AudioFormat format) {
-        byte[] out = new byte[in.length * format.getFrameSize()];
-        return AudioFloatConverter.getConverter(format).toByteArray(in, out);
-    }
-
-    static public void fadeUp(double[] data, int samples) {
-        double dsamples = samples;
-        for (int i = 0; i < samples; i++)
-            data[i] *= i / dsamples;
-    }
-
-    static public void fadeUp(float[] data, int samples) {
-        double dsamples = samples;
-        for (int i = 0; i < samples; i++)
-            data[i] *= i / dsamples;
-    }
-
-    static public double[] loopExtend(double[] data, int newsize) {
-        double[] outdata = new double[newsize];
-        int p_len = data.length;
-        int p_ps = 0;
-        for (int i = 0; i < outdata.length; i++) {
-            outdata[i] = data[p_ps];
-            p_ps++;
-            if (p_ps == p_len)
-                p_ps = 0;
-        }
-        return outdata;
-    }
-
-    static public float[] loopExtend(float[] data, int newsize) {
-        float[] outdata = new float[newsize];
-        int p_len = data.length;
-        int p_ps = 0;
-        for (int i = 0; i < outdata.length; i++) {
-            outdata[i] = data[p_ps];
-            p_ps++;
-            if (p_ps == p_len)
-                p_ps = 0;
-        }
-        return outdata;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Random;
+
+import javax.sound.midi.Patch;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * Emergency Soundbank generator.
+ * Used when no other default soundbank can be found.
+ *
+ * @author Karl Helgason
+ */
+public class EmergencySoundbank {
+
+    public static String[] general_midi_instruments = {
+        "Acoustic Grand Piano",
+        "Bright Acoustic Piano",
+        "Electric Grand Piano",
+        "Honky-tonk Piano",
+        "Electric Piano 1",
+        "Electric Piano 2",
+        "Harpsichord",
+        "Clavi",
+        "Celesta",
+        "Glockenspiel",
+        "Music Box",
+        "Vibraphone",
+        "Marimba",
+        "Xylophone",
+        "Tubular Bells",
+        "Dulcimer",
+        "Drawbar Organ",
+        "Percussive Organ",
+        "Rock Organ",
+        "Church Organ",
+        "Reed Organ",
+        "Accordion",
+        "Harmonica",
+        "Tango Accordion",
+        "Acoustic Guitar (nylon)",
+        "Acoustic Guitar (steel)",
+        "Electric Guitar (jazz)",
+        "Electric Guitar (clean)",
+        "Electric Guitar (muted)",
+        "Overdriven Guitar",
+        "Distortion Guitar",
+        "Guitar harmonics",
+        "Acoustic Bass",
+        "Electric Bass (finger)",
+        "Electric Bass (pick)",
+        "Fretless Bass",
+        "Slap Bass 1",
+        "Slap Bass 2",
+        "Synth Bass 1",
+        "Synth Bass 2",
+        "Violin",
+        "Viola",
+        "Cello",
+        "Contrabass",
+        "Tremolo Strings",
+        "Pizzicato Strings",
+        "Orchestral Harp",
+        "Timpani",
+        "String Ensemble 1",
+        "String Ensemble 2",
+        "SynthStrings 1",
+        "SynthStrings 2",
+        "Choir Aahs",
+        "Voice Oohs",
+        "Synth Voice",
+        "Orchestra Hit",
+        "Trumpet",
+        "Trombone",
+        "Tuba",
+        "Muted Trumpet",
+        "French Horn",
+        "Brass Section",
+        "SynthBrass 1",
+        "SynthBrass 2",
+        "Soprano Sax",
+        "Alto Sax",
+        "Tenor Sax",
+        "Baritone Sax",
+        "Oboe",
+        "English Horn",
+        "Bassoon",
+        "Clarinet",
+        "Piccolo",
+        "Flute",
+        "Recorder",
+        "Pan Flute",
+        "Blown Bottle",
+        "Shakuhachi",
+        "Whistle",
+        "Ocarina",
+        "Lead 1 (square)",
+        "Lead 2 (sawtooth)",
+        "Lead 3 (calliope)",
+        "Lead 4 (chiff)",
+        "Lead 5 (charang)",
+        "Lead 6 (voice)",
+        "Lead 7 (fifths)",
+        "Lead 8 (bass + lead)",
+        "Pad 1 (new age)",
+        "Pad 2 (warm)",
+        "Pad 3 (polysynth)",
+        "Pad 4 (choir)",
+        "Pad 5 (bowed)",
+        "Pad 6 (metallic)",
+        "Pad 7 (halo)",
+        "Pad 8 (sweep)",
+        "FX 1 (rain)",
+        "FX 2 (soundtrack)",
+        "FX 3 (crystal)",
+        "FX 4 (atmosphere)",
+        "FX 5 (brightness)",
+        "FX 6 (goblins)",
+        "FX 7 (echoes)",
+        "FX 8 (sci-fi)",
+        "Sitar",
+        "Banjo",
+        "Shamisen",
+        "Koto",
+        "Kalimba",
+        "Bag pipe",
+        "Fiddle",
+        "Shanai",
+        "Tinkle Bell",
+        "Agogo",
+        "Steel Drums",
+        "Woodblock",
+        "Taiko Drum",
+        "Melodic Tom",
+        "Synth Drum",
+        "Reverse Cymbal",
+        "Guitar Fret Noise",
+        "Breath Noise",
+        "Seashore",
+        "Bird Tweet",
+        "Telephone Ring",
+        "Helicopter",
+        "Applause",
+        "Gunshot"
+    };
+
+    public static SF2Soundbank createSoundbank() throws Exception {
+        SF2Soundbank sf2 = new SF2Soundbank();
+        sf2.setName("Emergency GM sound set");
+        sf2.setVendor("Generated");
+        sf2.setDescription("Emergency generated soundbank");
+
+        /*
+         *  percussion instruments
+         */
+
+        SF2Layer bass_drum = new_bass_drum(sf2);
+        SF2Layer snare_drum = new_snare_drum(sf2);
+        SF2Layer tom = new_tom(sf2);
+        SF2Layer open_hihat = new_open_hihat(sf2);
+        SF2Layer closed_hihat = new_closed_hihat(sf2);
+        SF2Layer crash_cymbal = new_crash_cymbal(sf2);
+        SF2Layer side_stick = new_side_stick(sf2);
+
+        SF2Layer[] drums = new SF2Layer[128];
+        drums[35] = bass_drum;
+        drums[36] = bass_drum;
+        drums[38] = snare_drum;
+        drums[40] = snare_drum;
+        drums[41] = tom;
+        drums[43] = tom;
+        drums[45] = tom;
+        drums[47] = tom;
+        drums[48] = tom;
+        drums[50] = tom;
+        drums[42] = closed_hihat;
+        drums[44] = closed_hihat;
+        drums[46] = open_hihat;
+        drums[49] = crash_cymbal;
+        drums[51] = crash_cymbal;
+        drums[52] = crash_cymbal;
+        drums[55] = crash_cymbal;
+        drums[57] = crash_cymbal;
+        drums[59] = crash_cymbal;
+
+        // Use side_stick for missing drums:
+        drums[37] = side_stick;
+        drums[39] = side_stick;
+        drums[53] = side_stick;
+        drums[54] = side_stick;
+        drums[56] = side_stick;
+        drums[58] = side_stick;
+        drums[69] = side_stick;
+        drums[70] = side_stick;
+        drums[75] = side_stick;
+        drums[60] = side_stick;
+        drums[61] = side_stick;
+        drums[62] = side_stick;
+        drums[63] = side_stick;
+        drums[64] = side_stick;
+        drums[65] = side_stick;
+        drums[66] = side_stick;
+        drums[67] = side_stick;
+        drums[68] = side_stick;
+        drums[71] = side_stick;
+        drums[72] = side_stick;
+        drums[73] = side_stick;
+        drums[74] = side_stick;
+        drums[76] = side_stick;
+        drums[77] = side_stick;
+        drums[78] = side_stick;
+        drums[79] = side_stick;
+        drums[80] = side_stick;
+        drums[81] = side_stick;
+
+
+        SF2Instrument drum_instrument = new SF2Instrument(sf2);
+        drum_instrument.setName("Standard Kit");
+        drum_instrument.setPatch(new ModelPatch(0, 0, true));
+        sf2.addInstrument(drum_instrument);
+        for (int i = 0; i < drums.length; i++) {
+            if (drums[i] != null) {
+                SF2InstrumentRegion region = new SF2InstrumentRegion();
+                region.setLayer(drums[i]);
+                region.putBytes(SF2InstrumentRegion.GENERATOR_KEYRANGE,
+                        new byte[]{(byte) i, (byte) i});
+                drum_instrument.getRegions().add(region);
+            }
+        }
+
+
+        /*
+         *  melodic instruments
+         */
+
+        SF2Layer gpiano = new_gpiano(sf2);
+        SF2Layer gpiano2 = new_gpiano2(sf2);
+        SF2Layer gpiano_hammer = new_piano_hammer(sf2);
+        SF2Layer piano1 = new_piano1(sf2);
+        SF2Layer epiano1 = new_epiano1(sf2);
+        SF2Layer epiano2 = new_epiano2(sf2);
+
+        SF2Layer guitar = new_guitar1(sf2);
+        SF2Layer guitar_pick = new_guitar_pick(sf2);
+        SF2Layer guitar_dist = new_guitar_dist(sf2);
+        SF2Layer bass1 = new_bass1(sf2);
+        SF2Layer bass2 = new_bass2(sf2);
+        SF2Layer synthbass = new_synthbass(sf2);
+        SF2Layer string2 = new_string2(sf2);
+        SF2Layer orchhit = new_orchhit(sf2);
+        SF2Layer choir = new_choir(sf2);
+        SF2Layer solostring = new_solostring(sf2);
+        SF2Layer organ = new_organ(sf2);
+        SF2Layer ch_organ = new_ch_organ(sf2);
+        SF2Layer bell = new_bell(sf2);
+        SF2Layer flute = new_flute(sf2);
+
+        SF2Layer timpani = new_timpani(sf2);
+        SF2Layer melodic_toms = new_melodic_toms(sf2);
+        SF2Layer trumpet = new_trumpet(sf2);
+        SF2Layer trombone = new_trombone(sf2);
+        SF2Layer brass_section = new_brass_section(sf2);
+        SF2Layer horn = new_horn(sf2);
+        SF2Layer sax = new_sax(sf2);
+        SF2Layer oboe = new_oboe(sf2);
+        SF2Layer bassoon = new_bassoon(sf2);
+        SF2Layer clarinet = new_clarinet(sf2);
+        SF2Layer reverse_cymbal = new_reverse_cymbal(sf2);
+
+        SF2Layer defaultsound = piano1;
+
+        newInstrument(sf2, "Piano", new Patch(0, 0), gpiano, gpiano_hammer);
+        newInstrument(sf2, "Piano", new Patch(0, 1), gpiano2, gpiano_hammer);
+        newInstrument(sf2, "Piano", new Patch(0, 2), piano1);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Honky-tonk Piano",
+                    new Patch(0, 3), piano1, piano1);
+            SF2InstrumentRegion region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 80);
+            region.putInteger(SF2Region.GENERATOR_FINETUNE, 30);
+            region = ins.getRegions().get(1);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 30);
+        }
+        newInstrument(sf2, "Rhodes", new Patch(0, 4), epiano2);
+        newInstrument(sf2, "Rhodes", new Patch(0, 5), epiano2);
+        newInstrument(sf2, "Clavinet", new Patch(0, 6), epiano1);
+        newInstrument(sf2, "Clavinet", new Patch(0, 7), epiano1);
+        newInstrument(sf2, "Rhodes", new Patch(0, 8), epiano2);
+        newInstrument(sf2, "Bell", new Patch(0, 9), bell);
+        newInstrument(sf2, "Bell", new Patch(0, 10), bell);
+        newInstrument(sf2, "Vibraphone", new Patch(0, 11), bell);
+        newInstrument(sf2, "Marimba", new Patch(0, 12), bell);
+        newInstrument(sf2, "Marimba", new Patch(0, 13), bell);
+        newInstrument(sf2, "Bell", new Patch(0, 14), bell);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 15), organ);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 16), organ);
+        newInstrument(sf2, "Perc Organ", new Patch(0, 17), organ);
+        newInstrument(sf2, "Rock Organ", new Patch(0, 18), organ);
+        newInstrument(sf2, "Church Organ", new Patch(0, 19), ch_organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 20), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 21), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 22), organ);
+        newInstrument(sf2, "Accordion", new Patch(0, 23), organ);
+        newInstrument(sf2, "Guitar", new Patch(0, 24), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 25), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 26), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 27), guitar, guitar_pick);
+        newInstrument(sf2, "Guitar", new Patch(0, 28), guitar, guitar_pick);
+        newInstrument(sf2, "Distorted Guitar", new Patch(0, 29), guitar_dist);
+        newInstrument(sf2, "Distorted Guitar", new Patch(0, 30), guitar_dist);
+        newInstrument(sf2, "Guitar", new Patch(0, 31), guitar, guitar_pick);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 32), bass1);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 33), bass1);
+        newInstrument(sf2, "Finger Bass", new Patch(0, 34), bass1);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 35), bass2);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 36), bass2);
+        newInstrument(sf2, "Frettless Bass", new Patch(0, 37), bass2);
+        newInstrument(sf2, "Synth Bass1", new Patch(0, 38), synthbass);
+        newInstrument(sf2, "Synth Bass2", new Patch(0, 39), synthbass);
+        newInstrument(sf2, "Solo String", new Patch(0, 40), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 41), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 42), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 43), string2, solostring);
+        newInstrument(sf2, "Solo String", new Patch(0, 44), string2, solostring);
+        newInstrument(sf2, "Def", new Patch(0, 45), defaultsound);
+        newInstrument(sf2, "Harp", new Patch(0, 46), bell);
+        newInstrument(sf2, "Timpani", new Patch(0, 47), timpani);
+        newInstrument(sf2, "Strings", new Patch(0, 48), string2);
+        SF2Instrument slow_strings =
+                newInstrument(sf2, "Slow Strings", new Patch(0, 49), string2);
+        SF2InstrumentRegion region = slow_strings.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, 2500);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 2000);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 50), string2);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 51), string2);
+
+
+        newInstrument(sf2, "Choir", new Patch(0, 52), choir);
+        newInstrument(sf2, "Choir", new Patch(0, 53), choir);
+        newInstrument(sf2, "Choir", new Patch(0, 54), choir);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Orch Hit",
+                    new Patch(0, 55), orchhit, orchhit, timpani);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_COARSETUNE, -12);
+            region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        }
+        newInstrument(sf2, "Trumpet", new Patch(0, 56), trumpet);
+        newInstrument(sf2, "Trombone", new Patch(0, 57), trombone);
+        newInstrument(sf2, "Trombone", new Patch(0, 58), trombone);
+        newInstrument(sf2, "Trumpet", new Patch(0, 59), trumpet);
+        newInstrument(sf2, "Horn", new Patch(0, 60), horn);
+        newInstrument(sf2, "Brass Section", new Patch(0, 61), brass_section);
+        newInstrument(sf2, "Brass Section", new Patch(0, 62), brass_section);
+        newInstrument(sf2, "Brass Section", new Patch(0, 63), brass_section);
+        newInstrument(sf2, "Sax", new Patch(0, 64), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 65), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 66), sax);
+        newInstrument(sf2, "Sax", new Patch(0, 67), sax);
+        newInstrument(sf2, "Oboe", new Patch(0, 68), oboe);
+        newInstrument(sf2, "Horn", new Patch(0, 69), horn);
+        newInstrument(sf2, "Bassoon", new Patch(0, 70), bassoon);
+        newInstrument(sf2, "Clarinet", new Patch(0, 71), clarinet);
+        newInstrument(sf2, "Flute", new Patch(0, 72), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 73), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 74), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 75), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 76), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 77), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 78), flute);
+        newInstrument(sf2, "Flute", new Patch(0, 79), flute);
+        newInstrument(sf2, "Organ", new Patch(0, 80), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 81), organ);
+        newInstrument(sf2, "Flute", new Patch(0, 82), flute);
+        newInstrument(sf2, "Organ", new Patch(0, 83), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 84), organ);
+        newInstrument(sf2, "Choir", new Patch(0, 85), choir);
+        newInstrument(sf2, "Organ", new Patch(0, 86), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 87), organ);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 88), string2);
+        newInstrument(sf2, "Organ", new Patch(0, 89), organ);
+        newInstrument(sf2, "Def", new Patch(0, 90), defaultsound);
+        newInstrument(sf2, "Choir", new Patch(0, 91), choir);
+        newInstrument(sf2, "Organ", new Patch(0, 92), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 93), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 94), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 95), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 96), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 97), organ);
+        newInstrument(sf2, "Bell", new Patch(0, 98), bell);
+        newInstrument(sf2, "Organ", new Patch(0, 99), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 100), organ);
+        newInstrument(sf2, "Organ", new Patch(0, 101), organ);
+        newInstrument(sf2, "Def", new Patch(0, 102), defaultsound);
+        newInstrument(sf2, "Synth Strings", new Patch(0, 103), string2);
+        newInstrument(sf2, "Def", new Patch(0, 104), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 105), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 106), defaultsound);
+        newInstrument(sf2, "Def", new Patch(0, 107), defaultsound);
+        newInstrument(sf2, "Marimba", new Patch(0, 108), bell);
+        newInstrument(sf2, "Sax", new Patch(0, 109), sax);
+        newInstrument(sf2, "Solo String", new Patch(0, 110), string2, solostring);
+        newInstrument(sf2, "Oboe", new Patch(0, 111), oboe);
+        newInstrument(sf2, "Bell", new Patch(0, 112), bell);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 113), melodic_toms);
+        newInstrument(sf2, "Marimba", new Patch(0, 114), bell);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 115), melodic_toms);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 116), melodic_toms);
+        newInstrument(sf2, "Melodic Toms", new Patch(0, 117), melodic_toms);
+        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 118), reverse_cymbal);
+        newInstrument(sf2, "Reverse Cymbal", new Patch(0, 119), reverse_cymbal);
+        newInstrument(sf2, "Guitar", new Patch(0, 120), guitar);
+        newInstrument(sf2, "Def", new Patch(0, 121), defaultsound);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
+                    new Patch(0, 122), reverse_cymbal);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
+            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
+        }
+        {
+            SF2Instrument ins = newInstrument(sf2, "Bird/Flute",
+                    new Patch(0, 123), flute);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_COARSETUNE, 24);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -3000);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        }
+        newInstrument(sf2, "Def", new Patch(0, 124), side_stick);
+        {
+            SF2Instrument ins = newInstrument(sf2, "Seashore/Reverse Cymbal",
+                    new Patch(0, 125), reverse_cymbal);
+            region = ins.getRegions().get(0);
+            region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+            region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 18500);
+            region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 4500);
+            region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, -4500);
+        }
+        newInstrument(sf2, "Applause/crash_cymbal",
+                new Patch(0, 126), crash_cymbal);
+        newInstrument(sf2, "Gunshot/side_stick", new Patch(0, 127), side_stick);
+
+        for (SF2Instrument instrument : sf2.getInstruments()) {
+            Patch patch = instrument.getPatch();
+            if (patch instanceof ModelPatch) {
+                if (((ModelPatch) patch).isPercussion())
+                    continue;
+            }
+            instrument.setName(general_midi_instruments[patch.getProgram()]);
+        }
+
+        return sf2;
+
+    }
+
+    public static SF2Layer new_bell(SF2Soundbank sf2) {
+        Random random = new Random(102030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.01;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar1(SF2Soundbank sf2) {
+
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 2;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[40];
+        for (int i = 0; i < 40; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] = 2;
+        aa[1] = 0.5;
+        aa[2] = 0.45;
+        aa[3] = 0.2;
+        aa[4] = 1;
+        aa[5] = 0.5;
+        aa[6] = 2;
+        aa[7] = 1;
+        aa[8] = 0.5;
+        aa[9] = 1;
+        aa[9] = 0.5;
+        aa[10] = 0.2;
+        aa[11] = 1;
+        aa[12] = 0.7;
+        aa[13] = 0.5;
+        aa[14] = 1;
+
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Guitar", data, base);
+        SF2Layer layer = newLayer(sf2, "Guitar", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -6000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar_dist(SF2Soundbank sf2) {
+
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 2;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[40];
+        for (int i = 0; i < 40; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] = 5;
+        aa[1] = 2;
+        aa[2] = 0.45;
+        aa[3] = 0.2;
+        aa[4] = 1;
+        aa[5] = 0.5;
+        aa[6] = 2;
+        aa[7] = 1;
+        aa[8] = 0.5;
+        aa[9] = 1;
+        aa[9] = 0.5;
+        aa[10] = 0.2;
+        aa[11] = 1;
+        aa[12] = 0.7;
+        aa[13] = 0.5;
+        aa[14] = 1;
+
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample_dist(sf2, "Distorted Guitar",
+                data, base, 10000.0);
+
+
+        SF2Layer layer = newLayer(sf2, "Distorted Guitar", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        //region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 2400);
+        //region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 200);
+
+        //region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -100);
+        //region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -1000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
+        //region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -20);
+        return layer;
+    }
+
+    public static SF2Layer new_guitar_pick(SF2Soundbank sf2) {
+
+        double datab[];
+
+        // Make treble part
+        {
+            int m = 2;
+            int fftlen = 4096 * m;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * m; i++) {
+                data[i] *= Math.exp(-Math.abs((i - 23) / ((double) m)) * 1.2)
+                        + Math.exp(-Math.abs((i - 40) / ((double) m)) * 0.9);
+            }
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9994;
+            }
+            datab = data;
+
+            fadeUp(data, 80);
+        }
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Guitar Noise", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Guitar Noise");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+//              region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+/*
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
+         */
+
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_gpiano(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 15.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 2;
+        //aa[2] *= 0.1;
+        aa[4] *= 2;
+
+
+        aa[12] *= 0.9;
+        aa[13] *= 0.7;
+        for (int i = 14; i < 30; i++) {
+            aa[i] *= 0.5;
+        }
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 10) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
+        return layer;
+    }
+
+    public static SF2Layer new_gpiano2(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 20.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 1;
+        //aa[2] *= 0.1;
+        aa[4] *= 2;
+
+
+        aa[12] *= 0.9;
+        aa[13] *= 0.7;
+        for (int i = 14; i < 30; i++) {
+            aa[i] *= 0.5;
+        }
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 10) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Grand Piano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "Grand Piano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -7000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 18000);
+        return layer;
+    }
+
+    public static SF2Layer new_piano_hammer(SF2Soundbank sf2) {
+
+        double datab[];
+
+        // Make treble part
+        {
+            int m = 2;
+            int fftlen = 4096 * m;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * m; i++)
+                data[i] *= Math.exp(-Math.abs((i - 37) / ((double) m)) * 0.05);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.6);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9997;
+            }
+            datab = data;
+
+            fadeUp(data, 80);
+        }
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Piano Hammer", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Piano Hammer");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+/*
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 0);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINMODENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 12000);
+         */
+
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_piano1(SF2Soundbank sf2) {
+        //Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_a = 0.2;
+        double end_a = 0.0001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 5;
+        aa[2] *= 0.1;
+        aa[7] *= 5;
+
+
+        for (int i = 0; i < 30; i++) {
+            //double detune = 1 + (random.nextDouble()*2 - 1)*0.0001;
+            double w = 0.2;
+            double ai = aa[i];
+            if (i > 12) {
+                w = 5;
+                ai *= 10;
+            }
+            int adjust = 0;
+            if (i > 5) {
+                adjust = (i - 5) * 7;
+            }
+            complexGaussianDist(data, base * (i + 1) + adjust, w, ai);
+        }
+
+        complexGaussianDist(data, base * (15.5), 1, 0.1);
+        complexGaussianDist(data, base * (17.5), 1, 0.01);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base, 200);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_epiano1(SF2Soundbank sf2) {
+        Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.0001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 1200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        return layer;
+    }
+
+    public static SF2Layer new_epiano2(SF2Soundbank sf2) {
+        Random random = new Random(302030201);
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.01;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double detune = 1 + (random.nextDouble() * 2 - 1) * 0.0001;
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1) * detune, w, a);
+            a *= a_step;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "EPiano", data, base);
+        SF2Layer layer = newLayer(sf2, "EPiano", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 8000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, 2400);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -9000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 16000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_bass1(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.02;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 8;
+        aa[1] *= 4;
+        aa[3] *= 8;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 11000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_synthbass(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.02;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 16;
+        aa[1] *= 4;
+        aa[3] *= 16;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, -3000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 8000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_bass2(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 0.05;
+        double end_w = 0.05;
+        double start_a = 0.2;
+        double end_a = 0.002;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 25.0);
+
+        double[] aa = new double[25];
+        for (int i = 0; i < 25; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 8;
+        aa[1] *= 4;
+        aa[3] *= 8;
+        aa[5] *= 8;
+
+        for (int i = 0; i < 25; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Bass2", data, base);
+        SF2Layer layer = newLayer(sf2, "Bass2", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        return layer;
+    }
+
+    public static SF2Layer new_solostring(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 2;
+        double start_a = 0.2;
+        double end_a = 0.01;
+
+        double[] aa = new double[18];
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[0] *= 5;
+        aa[1] *= 5;
+        aa[2] *= 5;
+        aa[3] *= 4;
+        aa[4] *= 4;
+        aa[5] *= 3;
+        aa[6] *= 3;
+        aa[7] *= 2;
+
+        for (int i = 0; i < aa.length; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        region.putInteger(SF2Region.GENERATOR_FREQVIBLFO, -1000);
+        region.putInteger(SF2Region.GENERATOR_VIBLFOTOPITCH, 15);
+        return layer;
+
+    }
+
+    public static SF2Layer new_orchhit(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+            a *= a_step;
+        }
+        complexGaussianDist(data, base * 4, 300, 1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Och Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Och Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 200);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 200);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_string2(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, a);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_choir(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 25;
+        double start_w = 2;
+        double end_w = 80;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        double[] aa = new double[40];
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[5] *= 0.1;
+        aa[6] *= 0.01;
+        aa[7] *= 0.1;
+        aa[8] *= 0.1;
+
+        for (int i = 0; i < aa.length; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Strings", data, base);
+        SF2Layer layer = newLayer(sf2, "Strings", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -5000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_organ(SF2Soundbank sf2) {
+        Random random = new Random(102030201);
+        int x = 1;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+
+        for (int i = 0; i < 12; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w,
+                    a * (0.5 + 3 * (random.nextDouble())));
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
+        SF2Layer layer = newLayer(sf2, "Organ", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_ch_organ(SF2Soundbank sf2) {
+        int x = 1;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+        double start_w = 0.01;
+        double end_w = 0.01;
+        double start_a = 0.2;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 60.0);
+
+        double[] aa = new double[60];
+        for (int i = 0; i < aa.length; i++) {
+            a *= a_step;
+            aa[i] = a;
+        }
+
+        aa[0] *= 5;
+        aa[1] *= 2;
+        aa[2] = 0;
+        aa[4] = 0;
+        aa[5] = 0;
+        aa[7] *= 7;
+        aa[9] = 0;
+        aa[10] = 0;
+        aa[12] = 0;
+        aa[15] *= 7;
+        aa[18] = 0;
+        aa[20] = 0;
+        aa[24] = 0;
+        aa[27] *= 5;
+        aa[29] = 0;
+        aa[30] = 0;
+        aa[33] = 0;
+        aa[36] *= 4;
+        aa[37] = 0;
+        aa[39] = 0;
+        aa[42] = 0;
+        aa[43] = 0;
+        aa[47] = 0;
+        aa[50] *= 4;
+        aa[52] = 0;
+        aa[55] = 0;
+        aa[57] = 0;
+
+
+        aa[10] *= 0.1;
+        aa[11] *= 0.1;
+        aa[12] *= 0.1;
+        aa[13] *= 0.1;
+
+        aa[17] *= 0.1;
+        aa[18] *= 0.1;
+        aa[19] *= 0.1;
+        aa[20] *= 0.1;
+
+        for (int i = 0; i < 60; i++) {
+            double w = start_w + (end_w - start_w) * (i / 40.0);
+            complexGaussianDist(data, base * (i + 1), w, aa[i]);
+            a *= a_step;
+        }
+        SF2Sample sample = newSimpleFFTSample(sf2, "Organ", data, base);
+        SF2Layer layer = newLayer(sf2, "Organ", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        return layer;
+
+    }
+
+    public static SF2Layer new_flute(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 1, 0.001, 0.5);
+        complexGaussianDist(data, base * 2, 0.001, 0.5);
+        complexGaussianDist(data, base * 3, 0.001, 0.5);
+        complexGaussianDist(data, base * 4, 0.01, 0.5);
+
+        complexGaussianDist(data, base * 4, 100, 120);
+        complexGaussianDist(data, base * 6, 100, 40);
+        complexGaussianDist(data, base * 8, 100, 80);
+
+        complexGaussianDist(data, base * 5, 0.001, 0.05);
+        complexGaussianDist(data, base * 6, 0.001, 0.06);
+        complexGaussianDist(data, base * 7, 0.001, 0.04);
+        complexGaussianDist(data, base * 8, 0.005, 0.06);
+        complexGaussianDist(data, base * 9, 0.005, 0.06);
+        complexGaussianDist(data, base * 10, 0.01, 0.1);
+        complexGaussianDist(data, base * 11, 0.08, 0.7);
+        complexGaussianDist(data, base * 12, 0.08, 0.6);
+        complexGaussianDist(data, base * 13, 0.08, 0.6);
+        complexGaussianDist(data, base * 14, 0.08, 0.6);
+        complexGaussianDist(data, base * 15, 0.08, 0.5);
+        complexGaussianDist(data, base * 16, 0.08, 0.5);
+        complexGaussianDist(data, base * 17, 0.08, 0.2);
+
+
+        complexGaussianDist(data, base * 1, 10, 8);
+        complexGaussianDist(data, base * 2, 10, 8);
+        complexGaussianDist(data, base * 3, 10, 8);
+        complexGaussianDist(data, base * 4, 10, 8);
+        complexGaussianDist(data, base * 5, 10, 8);
+        complexGaussianDist(data, base * 6, 20, 9);
+        complexGaussianDist(data, base * 7, 20, 9);
+        complexGaussianDist(data, base * 8, 20, 9);
+        complexGaussianDist(data, base * 9, 20, 8);
+        complexGaussianDist(data, base * 10, 30, 8);
+        complexGaussianDist(data, base * 11, 30, 9);
+        complexGaussianDist(data, base * 12, 30, 9);
+        complexGaussianDist(data, base * 13, 30, 8);
+        complexGaussianDist(data, base * 14, 30, 8);
+        complexGaussianDist(data, base * 15, 30, 7);
+        complexGaussianDist(data, base * 16, 30, 7);
+        complexGaussianDist(data, base * 17, 30, 6);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
+        SF2Layer layer = newLayer(sf2, "Flute", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_horn(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.00000000001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            if (i == 0)
+                complexGaussianDist(data, base * (i + 1), 0.1, a * 0.2);
+            else
+                complexGaussianDist(data, base * (i + 1), 0.1, a);
+            a *= a_step;
+        }
+
+        complexGaussianDist(data, base * 2, 100, 1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Horn", data, base);
+        SF2Layer layer = newLayer(sf2, "Horn", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -500);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_trumpet(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.00001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
+        double[] aa = new double[80];
+        for (int i = 0; i < 80; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.05;
+        aa[1] *= 0.2;
+        aa[2] *= 0.5;
+        aa[3] *= 0.85;
+
+        for (int i = 0; i < 80; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
+        }
+
+        complexGaussianDist(data, base * 5, 300, 3);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Trumpet", data, base);
+        SF2Layer layer = newLayer(sf2, "Trumpet", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -10000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 0);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -4000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, -2500);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
+        return layer;
+
+    }
+
+    public static SF2Layer new_brass_section(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.005;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 30.0);
+        double[] aa = new double[30];
+        for (int i = 0; i < 30; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.8;
+        aa[1] *= 0.9;
+
+        double w = 5;
+        for (int i = 0; i < 30; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1 * w, aa[i] * w);
+            w += 6; //*= w_step;
+        }
+
+        complexGaussianDist(data, base * 6, 300, 2);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Brass Section", data, base);
+        SF2Layer layer = newLayer(sf2, "Brass Section", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -9200);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_trombone(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.001;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 80.0);
+        double[] aa = new double[80];
+        for (int i = 0; i < 80; i++) {
+            aa[i] = a;
+            a *= a_step;
+        }
+
+        aa[0] *= 0.3;
+        aa[1] *= 0.7;
+
+        for (int i = 0; i < 80; i++) {
+            complexGaussianDist(data, base * (i + 1), 0.1, aa[i]);
+        }
+
+        complexGaussianDist(data, base * 6, 300, 2);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Trombone", data, base);
+        SF2Layer layer = newLayer(sf2, "Trombone", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -8000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -2000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERQ, 10);
+        return layer;
+
+    }
+
+    public static SF2Layer new_sax(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        double start_a = 0.5;
+        double end_a = 0.01;
+        double a = start_a;
+        double a_step = Math.pow(end_a / start_a, 1.0 / 40.0);
+        for (int i = 0; i < 40; i++) {
+            if (i == 0 || i == 2)
+                complexGaussianDist(data, base * (i + 1), 0.1, a * 4);
+            else
+                complexGaussianDist(data, base * (i + 1), 0.1, a);
+            a *= a_step;
+        }
+
+        complexGaussianDist(data, base * 4, 200, 1);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Sax", data, base);
+        SF2Layer layer = newLayer(sf2, "Sax", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+
+        region.putInteger(SF2Region.GENERATOR_ATTACKMODENV, -3000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEMODENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_MODENVTOFILTERFC, 5000);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 4500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_oboe(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 5, 100, 80);
+
+
+        complexGaussianDist(data, base * 1, 0.01, 0.53);
+        complexGaussianDist(data, base * 2, 0.01, 0.51);
+        complexGaussianDist(data, base * 3, 0.01, 0.48);
+        complexGaussianDist(data, base * 4, 0.01, 0.49);
+        complexGaussianDist(data, base * 5, 0.01, 5);
+        complexGaussianDist(data, base * 6, 0.01, 0.51);
+        complexGaussianDist(data, base * 7, 0.01, 0.50);
+        complexGaussianDist(data, base * 8, 0.01, 0.59);
+        complexGaussianDist(data, base * 9, 0.01, 0.61);
+        complexGaussianDist(data, base * 10, 0.01, 0.52);
+        complexGaussianDist(data, base * 11, 0.01, 0.49);
+        complexGaussianDist(data, base * 12, 0.01, 0.51);
+        complexGaussianDist(data, base * 13, 0.01, 0.48);
+        complexGaussianDist(data, base * 14, 0.01, 0.51);
+        complexGaussianDist(data, base * 15, 0.01, 0.46);
+        complexGaussianDist(data, base * 16, 0.01, 0.35);
+        complexGaussianDist(data, base * 17, 0.01, 0.20);
+        complexGaussianDist(data, base * 18, 0.01, 0.10);
+        complexGaussianDist(data, base * 19, 0.01, 0.5);
+        complexGaussianDist(data, base * 20, 0.01, 0.1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Oboe", data, base);
+        SF2Layer layer = newLayer(sf2, "Oboe", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_bassoon(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 2, 100, 40);
+        complexGaussianDist(data, base * 4, 100, 20);
+
+        complexGaussianDist(data, base * 1, 0.01, 0.53);
+        complexGaussianDist(data, base * 2, 0.01, 5);
+        complexGaussianDist(data, base * 3, 0.01, 0.51);
+        complexGaussianDist(data, base * 4, 0.01, 0.48);
+        complexGaussianDist(data, base * 5, 0.01, 1.49);
+        complexGaussianDist(data, base * 6, 0.01, 0.51);
+        complexGaussianDist(data, base * 7, 0.01, 0.50);
+        complexGaussianDist(data, base * 8, 0.01, 0.59);
+        complexGaussianDist(data, base * 9, 0.01, 0.61);
+        complexGaussianDist(data, base * 10, 0.01, 0.52);
+        complexGaussianDist(data, base * 11, 0.01, 0.49);
+        complexGaussianDist(data, base * 12, 0.01, 0.51);
+        complexGaussianDist(data, base * 13, 0.01, 0.48);
+        complexGaussianDist(data, base * 14, 0.01, 0.51);
+        complexGaussianDist(data, base * 15, 0.01, 0.46);
+        complexGaussianDist(data, base * 16, 0.01, 0.35);
+        complexGaussianDist(data, base * 17, 0.01, 0.20);
+        complexGaussianDist(data, base * 18, 0.01, 0.10);
+        complexGaussianDist(data, base * 19, 0.01, 0.5);
+        complexGaussianDist(data, base * 20, 0.01, 0.1);
+
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Flute", data, base);
+        SF2Layer layer = newLayer(sf2, "Flute", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_clarinet(SF2Soundbank sf2) {
+        int x = 8;
+        int fftsize = 4096 * x;
+        double[] data = new double[fftsize * 2];
+        double base = x * 15;
+
+        complexGaussianDist(data, base * 1, 0.001, 0.5);
+        complexGaussianDist(data, base * 2, 0.001, 0.02);
+        complexGaussianDist(data, base * 3, 0.001, 0.2);
+        complexGaussianDist(data, base * 4, 0.01, 0.1);
+
+        complexGaussianDist(data, base * 4, 100, 60);
+        complexGaussianDist(data, base * 6, 100, 20);
+        complexGaussianDist(data, base * 8, 100, 20);
+
+        complexGaussianDist(data, base * 5, 0.001, 0.1);
+        complexGaussianDist(data, base * 6, 0.001, 0.09);
+        complexGaussianDist(data, base * 7, 0.001, 0.02);
+        complexGaussianDist(data, base * 8, 0.005, 0.16);
+        complexGaussianDist(data, base * 9, 0.005, 0.96);
+        complexGaussianDist(data, base * 10, 0.01, 0.9);
+        complexGaussianDist(data, base * 11, 0.08, 1.2);
+        complexGaussianDist(data, base * 12, 0.08, 1.8);
+        complexGaussianDist(data, base * 13, 0.08, 1.6);
+        complexGaussianDist(data, base * 14, 0.08, 1.2);
+        complexGaussianDist(data, base * 15, 0.08, 0.9);
+        complexGaussianDist(data, base * 16, 0.08, 0.5);
+        complexGaussianDist(data, base * 17, 0.08, 0.2);
+
+
+        complexGaussianDist(data, base * 1, 10, 8);
+        complexGaussianDist(data, base * 2, 10, 8);
+        complexGaussianDist(data, base * 3, 10, 8);
+        complexGaussianDist(data, base * 4, 10, 8);
+        complexGaussianDist(data, base * 5, 10, 8);
+        complexGaussianDist(data, base * 6, 20, 9);
+        complexGaussianDist(data, base * 7, 20, 9);
+        complexGaussianDist(data, base * 8, 20, 9);
+        complexGaussianDist(data, base * 9, 20, 8);
+        complexGaussianDist(data, base * 10, 30, 8);
+        complexGaussianDist(data, base * 11, 30, 9);
+        complexGaussianDist(data, base * 12, 30, 9);
+        complexGaussianDist(data, base * 13, 30, 8);
+        complexGaussianDist(data, base * 14, 30, 8);
+        complexGaussianDist(data, base * 15, 30, 7);
+        complexGaussianDist(data, base * 16, 30, 7);
+        complexGaussianDist(data, base * 17, 30, 6);
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Clarinet", data, base);
+        SF2Layer layer = newLayer(sf2, "Clarinet", sample);
+        SF2Region region = layer.getRegions().get(0);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -6000);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 4000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, -100);
+        region.putInteger(SF2Region.GENERATOR_INITIALFILTERFC, 9500);
+        return layer;
+
+    }
+
+    public static SF2Layer new_timpani(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 8;
+            double[] data = new double[2 * fftlen];
+            double base = 48;
+            complexGaussianDist(data, base * 2, 0.2, 1);
+            complexGaussianDist(data, base * 3, 0.2, 0.7);
+            complexGaussianDist(data, base * 5, 10, 1);
+            complexGaussianDist(data, base * 6, 9, 1);
+            complexGaussianDist(data, base * 8, 15, 1);
+            complexGaussianDist(data, base * 9, 18, 0.8);
+            complexGaussianDist(data, base * 11, 21, 0.5);
+            complexGaussianDist(data, base * 13, 28, 0.3);
+            complexGaussianDist(data, base * 14, 22, 0.1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.5);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++) {
+                double g = (1.0 - (i / d_len));
+                data[i] *= g * g;
+            }
+            fadeUp(data, 40);
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2) {
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            }
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 300; i++) {
+                double g = (1.0 - (i / 300.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 24; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9998;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.02;
+
+        normalize(datab, 0.9);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Timpani", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Timpani");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_melodic_toms(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 30, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        normalize(datab, 0.99);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Melodic Toms", datab);
+        sample.setOriginalPitch(63);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Melodic Toms");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_reverse_cymbal(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 100; i++)
+                data[i] = 0;
+
+            for (int i = 0; i < 512 * 2; i++) {
+                double gain = (i / (512.0 * 2.0));
+                data[i] = 1 - gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Reverse Cymbal",
+                datah, 100, 20);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Reverse Cymbal");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_ATTACKVOLENV, -200);
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, -12000);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, -1000);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_snare_drum(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 24, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.5);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 300; i++) {
+                double g = (1.0 - (i / 300.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 24; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9998;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i];
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Snare Drum", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Snare Drum");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_bass_drum(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 1.8 * 5 + 1, 2, 1);
+            complexGaussianDist(data, 1.8 * 9 + 1, 2, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024; i < 2048; i++)
+                data[i] = 1.0 - (i - 1024) / 1024.0;
+            for (int i = 0; i < 512; i++)
+                data[i] = 10 * i / 512.0;
+            for (int i = 0; i < 10; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.999;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Bass Drum", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Bass Drum");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_tom(SF2Soundbank sf2) {
+
+        double datab[];
+        double datah[];
+
+        // Make Bass Part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            complexGaussianDist(data, 30, 0.5, 1);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.8);
+            data = realPart(data);
+
+            double d_len = data.length;
+            for (int i = 0; i < data.length; i++)
+                data[i] *= (1.0 - (i / d_len));
+            datab = data;
+        }
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < datah.length; i++)
+            datab[i] += datah[i] * 0.5;
+        for (int i = 0; i < 5; i++)
+            datab[i] *= i / 5.0;
+
+        normalize(datab, 0.99);
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Tom", datab);
+        sample.setOriginalPitch(50);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Tom");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        //region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -100);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_closed_hihat(SF2Soundbank sf2) {
+        double datah[];
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 2048; i++)
+                data[i] = 0.2 + 0.8 * (i / 2048.0);
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datah = data;
+        }
+
+        for (int i = 0; i < 5; i++)
+            datah[i] *= i / 5.0;
+        SF2Sample sample = newSimpleDrumSample(sf2, "Closed Hi-Hat", datah);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Closed Hi-Hat");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_open_hihat(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 200; i++)
+                data[i] = 0;
+            for (int i = 0; i < 2048 * 4; i++) {
+                double gain = (i / (2048.0 * 4.0));
+                data[i] = gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Open Hi-Hat", datah, 1000, 5);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Open Hi-Hat");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1500);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1500);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_EXCLUSIVECLASS, 1);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_crash_cymbal(SF2Soundbank sf2) {
+        double datah[];
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5));
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 0; i < 100; i++)
+                data[i] = 0;
+            for (int i = 0; i < 512 * 2; i++) {
+                double gain = (i / (512.0 * 2.0));
+                data[i] = gain;
+            }
+            datah = data;
+        }
+
+        SF2Sample sample = newSimpleFFTSample(sf2, "Crash Cymbal", datah, 1000, 5);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Crash Cymbal");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_DECAYVOLENV, 1800);
+        region.putInteger(SF2Region.GENERATOR_SAMPLEMODES, 1);
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 1800);
+        region.putInteger(SF2Region.GENERATOR_SUSTAINVOLENV, 1000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+    }
+
+    public static SF2Layer new_side_stick(SF2Soundbank sf2) {
+        double datab[];
+
+        // Make treble part
+        {
+            int fftlen = 4096 * 4;
+            double[] data = new double[2 * fftlen];
+            Random random = new Random(3049912);
+            for (int i = 0; i < data.length; i += 2)
+                data[i] = (2.0 * (random.nextDouble() - 0.5)) * 0.1;
+            fft(data);
+            // Remove all negative frequency
+            for (int i = fftlen / 2; i < data.length; i++)
+                data[i] = 0;
+            for (int i = 1024 * 4; i < 2048 * 4; i++)
+                data[i] = 1.0 - (i - 4096) / 4096.0;
+            for (int i = 0; i < 200; i++) {
+                double g = (1.0 - (i / 200.0));
+                data[i] *= 1.0 + 20 * g * g;
+            }
+            for (int i = 0; i < 30; i++)
+                data[i] = 0;
+            randomPhase(data, new Random(3049912));
+            ifft(data);
+            normalize(data, 0.9);
+            data = realPart(data);
+            double gain = 1.0;
+            for (int i = 0; i < data.length; i++) {
+                data[i] *= gain;
+                gain *= 0.9996;
+            }
+            datab = data;
+        }
+
+        for (int i = 0; i < 10; i++)
+            datab[i] *= i / 10.0;
+
+        SF2Sample sample = newSimpleDrumSample(sf2, "Side Stick", datab);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName("Side Stick");
+
+        SF2GlobalRegion global = new SF2GlobalRegion();
+        layer.setGlobalZone(global);
+        sf2.addResource(layer);
+
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.putInteger(SF2Region.GENERATOR_RELEASEVOLENV, 12000);
+        region.putInteger(SF2Region.GENERATOR_SCALETUNING, 0);
+        region.putInteger(SF2Region.GENERATOR_INITIALATTENUATION, -50);
+        region.setSample(sample);
+        layer.getRegions().add(region);
+
+        return layer;
+
+    }
+
+    public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name,
+            double[] data, double base) {
+        return newSimpleFFTSample(sf2, name, data, base, 10);
+    }
+
+    public static SF2Sample newSimpleFFTSample(SF2Soundbank sf2, String name,
+            double[] data, double base, int fadeuptime) {
+
+        int fftsize = data.length / 2;
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+        double basefreq = (base / fftsize) * format.getSampleRate() * 0.5;
+
+        randomPhase(data);
+        ifft(data);
+        data = realPart(data);
+        normalize(data, 0.9);
+        float[] fdata = toFloat(data);
+        fdata = loopExtend(fdata, fdata.length + 512);
+        fadeUp(fdata, fadeuptime);
+        byte[] bdata = toBytes(fdata, format);
+
+        /*
+         * Create SoundFont2 sample.
+         */
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName(name);
+        sample.setData(bdata);
+        sample.setStartLoop(256);
+        sample.setEndLoop(fftsize + 256);
+        sample.setSampleRate((long) format.getSampleRate());
+        double orgnote = (69 + 12)
+                + (12 * Math.log(basefreq / 440.0) / Math.log(2));
+        sample.setOriginalPitch((int) orgnote);
+        sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0));
+        sf2.addResource(sample);
+
+        return sample;
+    }
+
+    public static SF2Sample newSimpleFFTSample_dist(SF2Soundbank sf2,
+            String name, double[] data, double base, double preamp) {
+
+        int fftsize = data.length / 2;
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+        double basefreq = (base / fftsize) * format.getSampleRate() * 0.5;
+
+        randomPhase(data);
+        ifft(data);
+        data = realPart(data);
+
+        for (int i = 0; i < data.length; i++) {
+            data[i] = (1 - Math.exp(-Math.abs(data[i] * preamp)))
+                    * Math.signum(data[i]);
+        }
+
+        normalize(data, 0.9);
+        float[] fdata = toFloat(data);
+        fdata = loopExtend(fdata, fdata.length + 512);
+        fadeUp(fdata, 80);
+        byte[] bdata = toBytes(fdata, format);
+
+        /*
+         * Create SoundFont2 sample.
+         */
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName(name);
+        sample.setData(bdata);
+        sample.setStartLoop(256);
+        sample.setEndLoop(fftsize + 256);
+        sample.setSampleRate((long) format.getSampleRate());
+        double orgnote = (69 + 12)
+                + (12 * Math.log(basefreq / 440.0) / Math.log(2));
+        sample.setOriginalPitch((int) orgnote);
+        sample.setPitchCorrection((byte) (-(orgnote - (int) orgnote) * 100.0));
+        sf2.addResource(sample);
+
+        return sample;
+    }
+
+    public static SF2Sample newSimpleDrumSample(SF2Soundbank sf2, String name,
+            double[] data) {
+
+        int fftsize = data.length;
+        AudioFormat format = new AudioFormat(44100, 16, 1, true, false);
+
+        byte[] bdata = toBytes(toFloat(realPart(data)), format);
+
+        /*
+         * Create SoundFont2 sample.
+         */
+        SF2Sample sample = new SF2Sample(sf2);
+        sample.setName(name);
+        sample.setData(bdata);
+        sample.setStartLoop(256);
+        sample.setEndLoop(fftsize + 256);
+        sample.setSampleRate((long) format.getSampleRate());
+        sample.setOriginalPitch(60);
+        sf2.addResource(sample);
+
+        return sample;
+    }
+
+    public static SF2Layer newLayer(SF2Soundbank sf2, String name, SF2Sample sample) {
+        SF2LayerRegion region = new SF2LayerRegion();
+        region.setSample(sample);
+
+        SF2Layer layer = new SF2Layer(sf2);
+        layer.setName(name);
+        layer.getRegions().add(region);
+        sf2.addResource(layer);
+
+        return layer;
+    }
+
+    public static SF2Instrument newInstrument(SF2Soundbank sf2, String name,
+            Patch patch, SF2Layer... layers) {
+
+        /*
+         * Create SoundFont2 instrument.
+         */
+        SF2Instrument ins = new SF2Instrument(sf2);
+        ins.setPatch(patch);
+        ins.setName(name);
+        sf2.addInstrument(ins);
+
+        /*
+         * Create region for instrument.
+         */
+        for (int i = 0; i < layers.length; i++) {
+            SF2InstrumentRegion insregion = new SF2InstrumentRegion();
+            insregion.setLayer(layers[i]);
+            ins.getRegions().add(insregion);
+        }
+
+        return ins;
+    }
+
+    static public void ifft(double[] data) {
+        new FFT(data.length / 2, 1).transform(data);
+    }
+
+    static public void fft(double[] data) {
+        new FFT(data.length / 2, -1).transform(data);
+    }
+
+    public static void complexGaussianDist(double[] cdata, double m,
+            double s, double v) {
+        for (int x = 0; x < cdata.length / 4; x++) {
+            cdata[x * 2] += v * (1.0 / (s * Math.sqrt(2 * Math.PI))
+                    * Math.exp((-1.0 / 2.0) * Math.pow((x - m) / s, 2.0)));
+        }
+    }
+
+    static public void randomPhase(double[] data) {
+        for (int i = 0; i < data.length; i += 2) {
+            double phase = Math.random() * 2 * Math.PI;
+            double d = data[i];
+            data[i] = Math.sin(phase) * d;
+            data[i + 1] = Math.cos(phase) * d;
+        }
+    }
+
+    static public void randomPhase(double[] data, Random random) {
+        for (int i = 0; i < data.length; i += 2) {
+            double phase = random.nextDouble() * 2 * Math.PI;
+            double d = data[i];
+            data[i] = Math.sin(phase) * d;
+            data[i + 1] = Math.cos(phase) * d;
+        }
+    }
+
+    static public void normalize(double[] data, double target) {
+        double maxvalue = 0;
+        for (int i = 0; i < data.length; i++) {
+            if (data[i] > maxvalue)
+                maxvalue = data[i];
+            if (-data[i] > maxvalue)
+                maxvalue = -data[i];
+        }
+        if (maxvalue == 0)
+            return;
+        double gain = target / maxvalue;
+        for (int i = 0; i < data.length; i++)
+            data[i] *= gain;
+    }
+
+    static public void normalize(float[] data, double target) {
+        double maxvalue = 0.5;
+        for (int i = 0; i < data.length; i++) {
+            if (data[i * 2] > maxvalue)
+                maxvalue = data[i * 2];
+            if (-data[i * 2] > maxvalue)
+                maxvalue = -data[i * 2];
+        }
+        double gain = target / maxvalue;
+        for (int i = 0; i < data.length; i++)
+            data[i * 2] *= gain;
+    }
+
+    static public double[] realPart(double[] in) {
+        double[] out = new double[in.length / 2];
+        for (int i = 0; i < out.length; i++) {
+            out[i] = in[i * 2];
+        }
+        return out;
+    }
+
+    static public double[] imgPart(double[] in) {
+        double[] out = new double[in.length / 2];
+        for (int i = 0; i < out.length; i++) {
+            out[i] = in[i * 2];
+        }
+        return out;
+    }
+
+    static public float[] toFloat(double[] in) {
+        float[] out = new float[in.length];
+        for (int i = 0; i < out.length; i++) {
+            out[i] = (float) in[i];
+        }
+        return out;
+    }
+
+    static public byte[] toBytes(float[] in, AudioFormat format) {
+        byte[] out = new byte[in.length * format.getFrameSize()];
+        return AudioFloatConverter.getConverter(format).toByteArray(in, out);
+    }
+
+    static public void fadeUp(double[] data, int samples) {
+        double dsamples = samples;
+        for (int i = 0; i < samples; i++)
+            data[i] *= i / dsamples;
+    }
+
+    static public void fadeUp(float[] data, int samples) {
+        double dsamples = samples;
+        for (int i = 0; i < samples; i++)
+            data[i] *= i / dsamples;
+    }
+
+    static public double[] loopExtend(double[] data, int newsize) {
+        double[] outdata = new double[newsize];
+        int p_len = data.length;
+        int p_ps = 0;
+        for (int i = 0; i < outdata.length; i++) {
+            outdata[i] = data[p_ps];
+            p_ps++;
+            if (p_ps == p_len)
+                p_ps = 0;
+        }
+        return outdata;
+    }
+
+    static public float[] loopExtend(float[] data, int newsize) {
+        float[] outdata = new float[newsize];
+        int p_len = data.length;
+        int p_ps = 0;
+        for (int i = 0; i < outdata.length; i++) {
+            outdata[i] = data[p_ps];
+            p_ps++;
+            if (p_ps == p_len)
+                p_ps = 0;
+        }
+        return outdata;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/FFT.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/FFT.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,749 +1,749 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Fast Fourier Transformer.
- *
- * @author Karl Helgason
- */
-public final class FFT {
-
-    private double[] w;
-    private int fftFrameSize;
-    private int sign;
-    private int[] bitm_array;
-    private int fftFrameSize2;
-
-    // Sign = -1 is FFT, 1 is IFFT (inverse FFT)
-    // Data = Interlaced double array to be transformed.
-    // The order is: real (sin), complex (cos)
-    // Framesize must be power of 2
-    public FFT(int fftFrameSize, int sign) {
-        w = computeTwiddleFactors(fftFrameSize, sign);
-
-        this.fftFrameSize = fftFrameSize;
-        this.sign = sign;
-        fftFrameSize2 = fftFrameSize << 1;
-
-        // Pre-process Bit-Reversal
-        bitm_array = new int[fftFrameSize2];
-        for (int i = 2; i < fftFrameSize2; i += 2) {
-            int j;
-            int bitm;
-            for (bitm = 2, j = 0; bitm < fftFrameSize2; bitm <<= 1) {
-                if ((i & bitm) != 0)
-                    j++;
-                j <<= 1;
-            }
-            bitm_array[i] = j;
-        }
-
-    }
-
-    public void transform(double[] data) {
-        bitreversal(data);
-        calc(fftFrameSize, data, sign, w);
-    }
-
-    private final static double[] computeTwiddleFactors(int fftFrameSize,
-            int sign) {
-
-        int imax = (int) (Math.log(fftFrameSize) / Math.log(2.));
-
-        double[] warray = new double[(fftFrameSize - 1) * 4];
-        int w_index = 0;
-
-        for (int i = 0,  nstep = 2; i < imax; i++) {
-            int jmax = nstep;
-            nstep <<= 1;
-
-            double wr = 1.0;
-            double wi = 0.0;
-
-            double arg = Math.PI / (jmax >> 1);
-            double wfr = Math.cos(arg);
-            double wfi = sign * Math.sin(arg);
-
-            for (int j = 0; j < jmax; j += 2) {
-                warray[w_index++] = wr;
-                warray[w_index++] = wi;
-
-                double tempr = wr;
-                wr = tempr * wfr - wi * wfi;
-                wi = tempr * wfi + wi * wfr;
-            }
-        }
-
-        // PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex
-        // operators and 8 +/- complex operators)
-        {
-            w_index = 0;
-            int w_index2 = warray.length >> 1;
-            for (int i = 0,  nstep = 2; i < (imax - 1); i++) {
-                int jmax = nstep;
-                nstep *= 2;
-
-                int ii = w_index + jmax;
-                for (int j = 0; j < jmax; j += 2) {
-                    double wr = warray[w_index++];
-                    double wi = warray[w_index++];
-                    double wr1 = warray[ii++];
-                    double wi1 = warray[ii++];
-                    warray[w_index2++] = wr * wr1 - wi * wi1;
-                    warray[w_index2++] = wr * wi1 + wi * wr1;
-                }
-            }
-
-        }
-
-        return warray;
-    }
-
-    private final static void calc(int fftFrameSize, double[] data, int sign,
-            double[] w) {
-
-        final int fftFrameSize2 = fftFrameSize << 1;
-
-        int nstep = 2;
-
-        if (nstep >= fftFrameSize2)
-            return;
-        int i = nstep - 2;
-        if (sign == -1)
-            calcF4F(fftFrameSize, data, i, nstep, w);
-        else
-            calcF4I(fftFrameSize, data, i, nstep, w);
-
-    }
-
-    private final static void calcF2E(int fftFrameSize, double[] data, int i,
-            int nstep, double[] w) {
-        int jmax = nstep;
-        nstep <<= 1;
-        for (int n = 0; n < jmax; n += 2) {
-            double wr = w[i++];
-            double wi = w[i++];
-            int m = n + jmax;
-            double datam_r = data[m];
-            double datam_i = data[m + 1];
-            double datan_r = data[n];
-            double datan_i = data[n + 1];
-            double tempr = datam_r * wr - datam_i * wi;
-            double tempi = datam_r * wi + datam_i * wr;
-            data[m] = datan_r - tempr;
-            data[m + 1] = datan_i - tempi;
-            data[n] = datan_r + tempr;
-            data[n + 1] = datan_i + tempi;
-        }
-        return;
-
-    }
-
-    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
-    // complex operators
-    private final static void calcF4F(int fftFrameSize, double[] data, int i,
-            int nstep, double[] w) {
-        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
-        // Factor-4 Decomposition
-
-        int w_len = w.length >> 1;
-        while (nstep < fftFrameSize2) {
-
-            if (nstep << 2 == fftFrameSize2) {
-                // Goto Factor-4 Final Decomposition
-                // calcF4E(data, i, nstep, -1, w);
-                calcF4FE(fftFrameSize, data, i, nstep, w);
-                return;
-            }
-            int jmax = nstep;
-            int nnstep = nstep << 1;
-            if (nnstep == fftFrameSize2) {
-                // Factor-4 Decomposition not possible
-                calcF2E(fftFrameSize, data, i, nstep, w);
-                return;
-            }
-            nstep <<= 2;
-            int ii = i + jmax;
-            int iii = i + w_len;
-
-            {
-                i += 2;
-                ii += 2;
-                iii += 2;
-
-                for (int n = 0; n < fftFrameSize2; n += nstep) {
-                    int m = n + jmax;
-
-                    double datam1_r = data[m];
-                    double datam1_i = data[m + 1];
-                    double datan1_r = data[n];
-                    double datan1_i = data[n + 1];
-
-                    n += nnstep;
-                    m += nnstep;
-                    double datam2_r = data[m];
-                    double datam2_i = data[m + 1];
-                    double datan2_r = data[n];
-                    double datan2_i = data[n + 1];
-
-                    double tempr = datam1_r;
-                    double tempi = datam1_i;
-
-                    datam1_r = datan1_r - tempr;
-                    datam1_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    double n2w1r = datan2_r;
-                    double n2w1i = datan2_i;
-                    double m2ww1r = datam2_r;
-                    double m2ww1i = datam2_i;
-
-                    tempr = m2ww1r - n2w1r;
-                    tempi = m2ww1i - n2w1i;
-
-                    datam2_r = datam1_r + tempi;
-                    datam2_i = datam1_i - tempr;
-                    datam1_r = datam1_r - tempi;
-                    datam1_i = datam1_i + tempr;
-
-                    tempr = n2w1r + m2ww1r;
-                    tempi = n2w1i + m2ww1i;
-
-                    datan2_r = datan1_r - tempr;
-                    datan2_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    data[m] = datam2_r;
-                    data[m + 1] = datam2_i;
-                    data[n] = datan2_r;
-                    data[n + 1] = datan2_i;
-
-                    n -= nnstep;
-                    m -= nnstep;
-                    data[m] = datam1_r;
-                    data[m + 1] = datam1_i;
-                    data[n] = datan1_r;
-                    data[n + 1] = datan1_i;
-
-                }
-            }
-
-            for (int j = 2; j < jmax; j += 2) {
-                double wr = w[i++];
-                double wi = w[i++];
-                double wr1 = w[ii++];
-                double wi1 = w[ii++];
-                double wwr1 = w[iii++];
-                double wwi1 = w[iii++];
-                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
-                // precomputed!!!
-                // double wwi1 = wr * wi1 + wi * wr1;
-
-                for (int n = j; n < fftFrameSize2; n += nstep) {
-                    int m = n + jmax;
-
-                    double datam1_r = data[m];
-                    double datam1_i = data[m + 1];
-                    double datan1_r = data[n];
-                    double datan1_i = data[n + 1];
-
-                    n += nnstep;
-                    m += nnstep;
-                    double datam2_r = data[m];
-                    double datam2_i = data[m + 1];
-                    double datan2_r = data[n];
-                    double datan2_i = data[n + 1];
-
-                    double tempr = datam1_r * wr - datam1_i * wi;
-                    double tempi = datam1_r * wi + datam1_i * wr;
-
-                    datam1_r = datan1_r - tempr;
-                    datam1_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    double n2w1r = datan2_r * wr1 - datan2_i * wi1;
-                    double n2w1i = datan2_r * wi1 + datan2_i * wr1;
-                    double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
-                    double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
-
-                    tempr = m2ww1r - n2w1r;
-                    tempi = m2ww1i - n2w1i;
-
-                    datam2_r = datam1_r + tempi;
-                    datam2_i = datam1_i - tempr;
-                    datam1_r = datam1_r - tempi;
-                    datam1_i = datam1_i + tempr;
-
-                    tempr = n2w1r + m2ww1r;
-                    tempi = n2w1i + m2ww1i;
-
-                    datan2_r = datan1_r - tempr;
-                    datan2_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    data[m] = datam2_r;
-                    data[m + 1] = datam2_i;
-                    data[n] = datan2_r;
-                    data[n + 1] = datan2_i;
-
-                    n -= nnstep;
-                    m -= nnstep;
-                    data[m] = datam1_r;
-                    data[m + 1] = datam1_i;
-                    data[n] = datan1_r;
-                    data[n + 1] = datan1_i;
-                }
-            }
-
-            i += jmax << 1;
-
-        }
-
-        calcF2E(fftFrameSize, data, i, nstep, w);
-
-    }
-
-    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
-    // complex operators
-    private final static void calcF4I(int fftFrameSize, double[] data, int i,
-            int nstep, double[] w) {
-        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
-        // Factor-4 Decomposition
-
-        int w_len = w.length >> 1;
-        while (nstep < fftFrameSize2) {
-
-            if (nstep << 2 == fftFrameSize2) {
-                // Goto Factor-4 Final Decomposition
-                // calcF4E(data, i, nstep, 1, w);
-                calcF4IE(fftFrameSize, data, i, nstep, w);
-                return;
-            }
-            int jmax = nstep;
-            int nnstep = nstep << 1;
-            if (nnstep == fftFrameSize2) {
-                // Factor-4 Decomposition not possible
-                calcF2E(fftFrameSize, data, i, nstep, w);
-                return;
-            }
-            nstep <<= 2;
-            int ii = i + jmax;
-            int iii = i + w_len;
-            {
-                i += 2;
-                ii += 2;
-                iii += 2;
-
-                for (int n = 0; n < fftFrameSize2; n += nstep) {
-                    int m = n + jmax;
-
-                    double datam1_r = data[m];
-                    double datam1_i = data[m + 1];
-                    double datan1_r = data[n];
-                    double datan1_i = data[n + 1];
-
-                    n += nnstep;
-                    m += nnstep;
-                    double datam2_r = data[m];
-                    double datam2_i = data[m + 1];
-                    double datan2_r = data[n];
-                    double datan2_i = data[n + 1];
-
-                    double tempr = datam1_r;
-                    double tempi = datam1_i;
-
-                    datam1_r = datan1_r - tempr;
-                    datam1_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    double n2w1r = datan2_r;
-                    double n2w1i = datan2_i;
-                    double m2ww1r = datam2_r;
-                    double m2ww1i = datam2_i;
-
-                    tempr = n2w1r - m2ww1r;
-                    tempi = n2w1i - m2ww1i;
-
-                    datam2_r = datam1_r + tempi;
-                    datam2_i = datam1_i - tempr;
-                    datam1_r = datam1_r - tempi;
-                    datam1_i = datam1_i + tempr;
-
-                    tempr = n2w1r + m2ww1r;
-                    tempi = n2w1i + m2ww1i;
-
-                    datan2_r = datan1_r - tempr;
-                    datan2_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    data[m] = datam2_r;
-                    data[m + 1] = datam2_i;
-                    data[n] = datan2_r;
-                    data[n + 1] = datan2_i;
-
-                    n -= nnstep;
-                    m -= nnstep;
-                    data[m] = datam1_r;
-                    data[m + 1] = datam1_i;
-                    data[n] = datan1_r;
-                    data[n + 1] = datan1_i;
-
-                }
-
-            }
-            for (int j = 2; j < jmax; j += 2) {
-                double wr = w[i++];
-                double wi = w[i++];
-                double wr1 = w[ii++];
-                double wi1 = w[ii++];
-                double wwr1 = w[iii++];
-                double wwi1 = w[iii++];
-                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
-                // precomputed!!!
-                // double wwi1 = wr * wi1 + wi * wr1;
-
-                for (int n = j; n < fftFrameSize2; n += nstep) {
-                    int m = n + jmax;
-
-                    double datam1_r = data[m];
-                    double datam1_i = data[m + 1];
-                    double datan1_r = data[n];
-                    double datan1_i = data[n + 1];
-
-                    n += nnstep;
-                    m += nnstep;
-                    double datam2_r = data[m];
-                    double datam2_i = data[m + 1];
-                    double datan2_r = data[n];
-                    double datan2_i = data[n + 1];
-
-                    double tempr = datam1_r * wr - datam1_i * wi;
-                    double tempi = datam1_r * wi + datam1_i * wr;
-
-                    datam1_r = datan1_r - tempr;
-                    datam1_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    double n2w1r = datan2_r * wr1 - datan2_i * wi1;
-                    double n2w1i = datan2_r * wi1 + datan2_i * wr1;
-                    double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
-                    double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
-
-                    tempr = n2w1r - m2ww1r;
-                    tempi = n2w1i - m2ww1i;
-
-                    datam2_r = datam1_r + tempi;
-                    datam2_i = datam1_i - tempr;
-                    datam1_r = datam1_r - tempi;
-                    datam1_i = datam1_i + tempr;
-
-                    tempr = n2w1r + m2ww1r;
-                    tempi = n2w1i + m2ww1i;
-
-                    datan2_r = datan1_r - tempr;
-                    datan2_i = datan1_i - tempi;
-                    datan1_r = datan1_r + tempr;
-                    datan1_i = datan1_i + tempi;
-
-                    data[m] = datam2_r;
-                    data[m + 1] = datam2_i;
-                    data[n] = datan2_r;
-                    data[n + 1] = datan2_i;
-
-                    n -= nnstep;
-                    m -= nnstep;
-                    data[m] = datam1_r;
-                    data[m + 1] = datam1_i;
-                    data[n] = datan1_r;
-                    data[n + 1] = datan1_i;
-
-                }
-            }
-
-            i += jmax << 1;
-
-        }
-
-        calcF2E(fftFrameSize, data, i, nstep, w);
-
-    }
-
-    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
-    // complex operators
-    private final static void calcF4FE(int fftFrameSize, double[] data, int i,
-            int nstep, double[] w) {
-        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
-        // Factor-4 Decomposition
-
-        int w_len = w.length >> 1;
-        while (nstep < fftFrameSize2) {
-
-            int jmax = nstep;
-            int nnstep = nstep << 1;
-            if (nnstep == fftFrameSize2) {
-                // Factor-4 Decomposition not possible
-                calcF2E(fftFrameSize, data, i, nstep, w);
-                return;
-            }
-            nstep <<= 2;
-            int ii = i + jmax;
-            int iii = i + w_len;
-            for (int n = 0; n < jmax; n += 2) {
-                double wr = w[i++];
-                double wi = w[i++];
-                double wr1 = w[ii++];
-                double wi1 = w[ii++];
-                double wwr1 = w[iii++];
-                double wwi1 = w[iii++];
-                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
-                // precomputed!!!
-                // double wwi1 = wr * wi1 + wi * wr1;
-
-                int m = n + jmax;
-
-                double datam1_r = data[m];
-                double datam1_i = data[m + 1];
-                double datan1_r = data[n];
-                double datan1_i = data[n + 1];
-
-                n += nnstep;
-                m += nnstep;
-                double datam2_r = data[m];
-                double datam2_i = data[m + 1];
-                double datan2_r = data[n];
-                double datan2_i = data[n + 1];
-
-                double tempr = datam1_r * wr - datam1_i * wi;
-                double tempi = datam1_r * wi + datam1_i * wr;
-
-                datam1_r = datan1_r - tempr;
-                datam1_i = datan1_i - tempi;
-                datan1_r = datan1_r + tempr;
-                datan1_i = datan1_i + tempi;
-
-                double n2w1r = datan2_r * wr1 - datan2_i * wi1;
-                double n2w1i = datan2_r * wi1 + datan2_i * wr1;
-                double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
-                double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
-
-                tempr = m2ww1r - n2w1r;
-                tempi = m2ww1i - n2w1i;
-
-                datam2_r = datam1_r + tempi;
-                datam2_i = datam1_i - tempr;
-                datam1_r = datam1_r - tempi;
-                datam1_i = datam1_i + tempr;
-
-                tempr = n2w1r + m2ww1r;
-                tempi = n2w1i + m2ww1i;
-
-                datan2_r = datan1_r - tempr;
-                datan2_i = datan1_i - tempi;
-                datan1_r = datan1_r + tempr;
-                datan1_i = datan1_i + tempi;
-
-                data[m] = datam2_r;
-                data[m + 1] = datam2_i;
-                data[n] = datan2_r;
-                data[n + 1] = datan2_i;
-
-                n -= nnstep;
-                m -= nnstep;
-                data[m] = datam1_r;
-                data[m + 1] = datam1_i;
-                data[n] = datan1_r;
-                data[n + 1] = datan1_i;
-
-            }
-
-            i += jmax << 1;
-
-        }
-
-    }
-
-    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
-    // complex operators
-    private final static void calcF4IE(int fftFrameSize, double[] data, int i,
-            int nstep, double[] w) {
-        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
-        // Factor-4 Decomposition
-
-        int w_len = w.length >> 1;
-        while (nstep < fftFrameSize2) {
-
-            int jmax = nstep;
-            int nnstep = nstep << 1;
-            if (nnstep == fftFrameSize2) {
-                // Factor-4 Decomposition not possible
-                calcF2E(fftFrameSize, data, i, nstep, w);
-                return;
-            }
-            nstep <<= 2;
-            int ii = i + jmax;
-            int iii = i + w_len;
-            for (int n = 0; n < jmax; n += 2) {
-                double wr = w[i++];
-                double wi = w[i++];
-                double wr1 = w[ii++];
-                double wi1 = w[ii++];
-                double wwr1 = w[iii++];
-                double wwi1 = w[iii++];
-                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
-                // precomputed!!!
-                // double wwi1 = wr * wi1 + wi * wr1;
-
-                int m = n + jmax;
-
-                double datam1_r = data[m];
-                double datam1_i = data[m + 1];
-                double datan1_r = data[n];
-                double datan1_i = data[n + 1];
-
-                n += nnstep;
-                m += nnstep;
-                double datam2_r = data[m];
-                double datam2_i = data[m + 1];
-                double datan2_r = data[n];
-                double datan2_i = data[n + 1];
-
-                double tempr = datam1_r * wr - datam1_i * wi;
-                double tempi = datam1_r * wi + datam1_i * wr;
-
-                datam1_r = datan1_r - tempr;
-                datam1_i = datan1_i - tempi;
-                datan1_r = datan1_r + tempr;
-                datan1_i = datan1_i + tempi;
-
-                double n2w1r = datan2_r * wr1 - datan2_i * wi1;
-                double n2w1i = datan2_r * wi1 + datan2_i * wr1;
-                double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
-                double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
-
-                tempr = n2w1r - m2ww1r;
-                tempi = n2w1i - m2ww1i;
-
-                datam2_r = datam1_r + tempi;
-                datam2_i = datam1_i - tempr;
-                datam1_r = datam1_r - tempi;
-                datam1_i = datam1_i + tempr;
-
-                tempr = n2w1r + m2ww1r;
-                tempi = n2w1i + m2ww1i;
-
-                datan2_r = datan1_r - tempr;
-                datan2_i = datan1_i - tempi;
-                datan1_r = datan1_r + tempr;
-                datan1_i = datan1_i + tempi;
-
-                data[m] = datam2_r;
-                data[m + 1] = datam2_i;
-                data[n] = datan2_r;
-                data[n + 1] = datan2_i;
-
-                n -= nnstep;
-                m -= nnstep;
-                data[m] = datam1_r;
-                data[m + 1] = datam1_i;
-                data[n] = datan1_r;
-                data[n + 1] = datan1_i;
-
-            }
-
-            i += jmax << 1;
-
-        }
-
-    }
-
-    private final void bitreversal(double[] data) {
-        if (fftFrameSize < 4)
-            return;
-
-        int inverse = fftFrameSize2 - 2;
-        for (int i = 0; i < fftFrameSize; i += 4) {
-            int j = bitm_array[i];
-
-            // Performing Bit-Reversal, even v.s. even, O(2N)
-            if (i < j) {
-
-                int n = i;
-                int m = j;
-
-                // COMPLEX: SWAP(data[n], data[m])
-                // Real Part
-                double tempr = data[n];
-                data[n] = data[m];
-                data[m] = tempr;
-                // Imagery Part
-                n++;
-                m++;
-                double tempi = data[n];
-                data[n] = data[m];
-                data[m] = tempi;
-
-                n = inverse - i;
-                m = inverse - j;
-
-                // COMPLEX: SWAP(data[n], data[m])
-                // Real Part
-                tempr = data[n];
-                data[n] = data[m];
-                data[m] = tempr;
-                // Imagery Part
-                n++;
-                m++;
-                tempi = data[n];
-                data[n] = data[m];
-                data[m] = tempi;
-            }
-
-            // Performing Bit-Reversal, odd v.s. even, O(N)
-
-            int m = j + fftFrameSize; // bitm_array[i+2];
-            // COMPLEX: SWAP(data[n], data[m])
-            // Real Part
-            int n = i + 2;
-            double tempr = data[n];
-            data[n] = data[m];
-            data[m] = tempr;
-            // Imagery Part
-            n++;
-            m++;
-            double tempi = data[n];
-            data[n] = data[m];
-            data[m] = tempi;
-        }
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Fast Fourier Transformer.
+ *
+ * @author Karl Helgason
+ */
+public final class FFT {
+
+    private double[] w;
+    private int fftFrameSize;
+    private int sign;
+    private int[] bitm_array;
+    private int fftFrameSize2;
+
+    // Sign = -1 is FFT, 1 is IFFT (inverse FFT)
+    // Data = Interlaced double array to be transformed.
+    // The order is: real (sin), complex (cos)
+    // Framesize must be power of 2
+    public FFT(int fftFrameSize, int sign) {
+        w = computeTwiddleFactors(fftFrameSize, sign);
+
+        this.fftFrameSize = fftFrameSize;
+        this.sign = sign;
+        fftFrameSize2 = fftFrameSize << 1;
+
+        // Pre-process Bit-Reversal
+        bitm_array = new int[fftFrameSize2];
+        for (int i = 2; i < fftFrameSize2; i += 2) {
+            int j;
+            int bitm;
+            for (bitm = 2, j = 0; bitm < fftFrameSize2; bitm <<= 1) {
+                if ((i & bitm) != 0)
+                    j++;
+                j <<= 1;
+            }
+            bitm_array[i] = j;
+        }
+
+    }
+
+    public void transform(double[] data) {
+        bitreversal(data);
+        calc(fftFrameSize, data, sign, w);
+    }
+
+    private final static double[] computeTwiddleFactors(int fftFrameSize,
+            int sign) {
+
+        int imax = (int) (Math.log(fftFrameSize) / Math.log(2.));
+
+        double[] warray = new double[(fftFrameSize - 1) * 4];
+        int w_index = 0;
+
+        for (int i = 0,  nstep = 2; i < imax; i++) {
+            int jmax = nstep;
+            nstep <<= 1;
+
+            double wr = 1.0;
+            double wi = 0.0;
+
+            double arg = Math.PI / (jmax >> 1);
+            double wfr = Math.cos(arg);
+            double wfi = sign * Math.sin(arg);
+
+            for (int j = 0; j < jmax; j += 2) {
+                warray[w_index++] = wr;
+                warray[w_index++] = wi;
+
+                double tempr = wr;
+                wr = tempr * wfr - wi * wfi;
+                wi = tempr * wfi + wi * wfr;
+            }
+        }
+
+        // PRECOMPUTATION of wwr1, wwi1 for factor 4 Decomposition (3 * complex
+        // operators and 8 +/- complex operators)
+        {
+            w_index = 0;
+            int w_index2 = warray.length >> 1;
+            for (int i = 0,  nstep = 2; i < (imax - 1); i++) {
+                int jmax = nstep;
+                nstep *= 2;
+
+                int ii = w_index + jmax;
+                for (int j = 0; j < jmax; j += 2) {
+                    double wr = warray[w_index++];
+                    double wi = warray[w_index++];
+                    double wr1 = warray[ii++];
+                    double wi1 = warray[ii++];
+                    warray[w_index2++] = wr * wr1 - wi * wi1;
+                    warray[w_index2++] = wr * wi1 + wi * wr1;
+                }
+            }
+
+        }
+
+        return warray;
+    }
+
+    private final static void calc(int fftFrameSize, double[] data, int sign,
+            double[] w) {
+
+        final int fftFrameSize2 = fftFrameSize << 1;
+
+        int nstep = 2;
+
+        if (nstep >= fftFrameSize2)
+            return;
+        int i = nstep - 2;
+        if (sign == -1)
+            calcF4F(fftFrameSize, data, i, nstep, w);
+        else
+            calcF4I(fftFrameSize, data, i, nstep, w);
+
+    }
+
+    private final static void calcF2E(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        int jmax = nstep;
+        nstep <<= 1;
+        for (int n = 0; n < jmax; n += 2) {
+            double wr = w[i++];
+            double wi = w[i++];
+            int m = n + jmax;
+            double datam_r = data[m];
+            double datam_i = data[m + 1];
+            double datan_r = data[n];
+            double datan_i = data[n + 1];
+            double tempr = datam_r * wr - datam_i * wi;
+            double tempi = datam_r * wi + datam_i * wr;
+            data[m] = datan_r - tempr;
+            data[m + 1] = datan_i - tempi;
+            data[n] = datan_r + tempr;
+            data[n + 1] = datan_i + tempi;
+        }
+        return;
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4F(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            if (nstep << 2 == fftFrameSize2) {
+                // Goto Factor-4 Final Decomposition
+                // calcF4E(data, i, nstep, -1, w);
+                calcF4FE(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+
+            {
+                i += 2;
+                ii += 2;
+                iii += 2;
+
+                for (int n = 0; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r;
+                    double tempi = datam1_i;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r;
+                    double n2w1i = datan2_i;
+                    double m2ww1r = datam2_r;
+                    double m2ww1i = datam2_i;
+
+                    tempr = m2ww1r - n2w1r;
+                    tempi = m2ww1i - n2w1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+
+                }
+            }
+
+            for (int j = 2; j < jmax; j += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                for (int n = j; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r * wr - datam1_i * wi;
+                    double tempi = datam1_r * wi + datam1_i * wr;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                    double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                    double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                    double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                    tempr = m2ww1r - n2w1r;
+                    tempi = m2ww1i - n2w1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+                }
+            }
+
+            i += jmax << 1;
+
+        }
+
+        calcF2E(fftFrameSize, data, i, nstep, w);
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4I(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            if (nstep << 2 == fftFrameSize2) {
+                // Goto Factor-4 Final Decomposition
+                // calcF4E(data, i, nstep, 1, w);
+                calcF4IE(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+            {
+                i += 2;
+                ii += 2;
+                iii += 2;
+
+                for (int n = 0; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r;
+                    double tempi = datam1_i;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r;
+                    double n2w1i = datan2_i;
+                    double m2ww1r = datam2_r;
+                    double m2ww1i = datam2_i;
+
+                    tempr = n2w1r - m2ww1r;
+                    tempi = n2w1i - m2ww1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+
+                }
+
+            }
+            for (int j = 2; j < jmax; j += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                for (int n = j; n < fftFrameSize2; n += nstep) {
+                    int m = n + jmax;
+
+                    double datam1_r = data[m];
+                    double datam1_i = data[m + 1];
+                    double datan1_r = data[n];
+                    double datan1_i = data[n + 1];
+
+                    n += nnstep;
+                    m += nnstep;
+                    double datam2_r = data[m];
+                    double datam2_i = data[m + 1];
+                    double datan2_r = data[n];
+                    double datan2_i = data[n + 1];
+
+                    double tempr = datam1_r * wr - datam1_i * wi;
+                    double tempi = datam1_r * wi + datam1_i * wr;
+
+                    datam1_r = datan1_r - tempr;
+                    datam1_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                    double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                    double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                    double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                    tempr = n2w1r - m2ww1r;
+                    tempi = n2w1i - m2ww1i;
+
+                    datam2_r = datam1_r + tempi;
+                    datam2_i = datam1_i - tempr;
+                    datam1_r = datam1_r - tempi;
+                    datam1_i = datam1_i + tempr;
+
+                    tempr = n2w1r + m2ww1r;
+                    tempi = n2w1i + m2ww1i;
+
+                    datan2_r = datan1_r - tempr;
+                    datan2_i = datan1_i - tempi;
+                    datan1_r = datan1_r + tempr;
+                    datan1_i = datan1_i + tempi;
+
+                    data[m] = datam2_r;
+                    data[m + 1] = datam2_i;
+                    data[n] = datan2_r;
+                    data[n + 1] = datan2_i;
+
+                    n -= nnstep;
+                    m -= nnstep;
+                    data[m] = datam1_r;
+                    data[m + 1] = datam1_i;
+                    data[n] = datan1_r;
+                    data[n + 1] = datan1_i;
+
+                }
+            }
+
+            i += jmax << 1;
+
+        }
+
+        calcF2E(fftFrameSize, data, i, nstep, w);
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4FE(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+            for (int n = 0; n < jmax; n += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                int m = n + jmax;
+
+                double datam1_r = data[m];
+                double datam1_i = data[m + 1];
+                double datan1_r = data[n];
+                double datan1_i = data[n + 1];
+
+                n += nnstep;
+                m += nnstep;
+                double datam2_r = data[m];
+                double datam2_i = data[m + 1];
+                double datan2_r = data[n];
+                double datan2_i = data[n + 1];
+
+                double tempr = datam1_r * wr - datam1_i * wi;
+                double tempi = datam1_r * wi + datam1_i * wr;
+
+                datam1_r = datan1_r - tempr;
+                datam1_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                tempr = m2ww1r - n2w1r;
+                tempi = m2ww1i - n2w1i;
+
+                datam2_r = datam1_r + tempi;
+                datam2_i = datam1_i - tempr;
+                datam1_r = datam1_r - tempi;
+                datam1_i = datam1_i + tempr;
+
+                tempr = n2w1r + m2ww1r;
+                tempi = n2w1i + m2ww1i;
+
+                datan2_r = datan1_r - tempr;
+                datan2_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                data[m] = datam2_r;
+                data[m + 1] = datam2_i;
+                data[n] = datan2_r;
+                data[n + 1] = datan2_i;
+
+                n -= nnstep;
+                m -= nnstep;
+                data[m] = datam1_r;
+                data[m + 1] = datam1_i;
+                data[n] = datan1_r;
+                data[n + 1] = datan1_i;
+
+            }
+
+            i += jmax << 1;
+
+        }
+
+    }
+
+    // Perform Factor-4 Decomposition with 3 * complex operators and 8 +/-
+    // complex operators
+    private final static void calcF4IE(int fftFrameSize, double[] data, int i,
+            int nstep, double[] w) {
+        final int fftFrameSize2 = fftFrameSize << 1; // 2*fftFrameSize;
+        // Factor-4 Decomposition
+
+        int w_len = w.length >> 1;
+        while (nstep < fftFrameSize2) {
+
+            int jmax = nstep;
+            int nnstep = nstep << 1;
+            if (nnstep == fftFrameSize2) {
+                // Factor-4 Decomposition not possible
+                calcF2E(fftFrameSize, data, i, nstep, w);
+                return;
+            }
+            nstep <<= 2;
+            int ii = i + jmax;
+            int iii = i + w_len;
+            for (int n = 0; n < jmax; n += 2) {
+                double wr = w[i++];
+                double wi = w[i++];
+                double wr1 = w[ii++];
+                double wi1 = w[ii++];
+                double wwr1 = w[iii++];
+                double wwi1 = w[iii++];
+                // double wwr1 = wr * wr1 - wi * wi1; // these numbers can be
+                // precomputed!!!
+                // double wwi1 = wr * wi1 + wi * wr1;
+
+                int m = n + jmax;
+
+                double datam1_r = data[m];
+                double datam1_i = data[m + 1];
+                double datan1_r = data[n];
+                double datan1_i = data[n + 1];
+
+                n += nnstep;
+                m += nnstep;
+                double datam2_r = data[m];
+                double datam2_i = data[m + 1];
+                double datan2_r = data[n];
+                double datan2_i = data[n + 1];
+
+                double tempr = datam1_r * wr - datam1_i * wi;
+                double tempi = datam1_r * wi + datam1_i * wr;
+
+                datam1_r = datan1_r - tempr;
+                datam1_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                double n2w1r = datan2_r * wr1 - datan2_i * wi1;
+                double n2w1i = datan2_r * wi1 + datan2_i * wr1;
+                double m2ww1r = datam2_r * wwr1 - datam2_i * wwi1;
+                double m2ww1i = datam2_r * wwi1 + datam2_i * wwr1;
+
+                tempr = n2w1r - m2ww1r;
+                tempi = n2w1i - m2ww1i;
+
+                datam2_r = datam1_r + tempi;
+                datam2_i = datam1_i - tempr;
+                datam1_r = datam1_r - tempi;
+                datam1_i = datam1_i + tempr;
+
+                tempr = n2w1r + m2ww1r;
+                tempi = n2w1i + m2ww1i;
+
+                datan2_r = datan1_r - tempr;
+                datan2_i = datan1_i - tempi;
+                datan1_r = datan1_r + tempr;
+                datan1_i = datan1_i + tempi;
+
+                data[m] = datam2_r;
+                data[m + 1] = datam2_i;
+                data[n] = datan2_r;
+                data[n + 1] = datan2_i;
+
+                n -= nnstep;
+                m -= nnstep;
+                data[m] = datam1_r;
+                data[m + 1] = datam1_i;
+                data[n] = datan1_r;
+                data[n + 1] = datan1_i;
+
+            }
+
+            i += jmax << 1;
+
+        }
+
+    }
+
+    private final void bitreversal(double[] data) {
+        if (fftFrameSize < 4)
+            return;
+
+        int inverse = fftFrameSize2 - 2;
+        for (int i = 0; i < fftFrameSize; i += 4) {
+            int j = bitm_array[i];
+
+            // Performing Bit-Reversal, even v.s. even, O(2N)
+            if (i < j) {
+
+                int n = i;
+                int m = j;
+
+                // COMPLEX: SWAP(data[n], data[m])
+                // Real Part
+                double tempr = data[n];
+                data[n] = data[m];
+                data[m] = tempr;
+                // Imagery Part
+                n++;
+                m++;
+                double tempi = data[n];
+                data[n] = data[m];
+                data[m] = tempi;
+
+                n = inverse - i;
+                m = inverse - j;
+
+                // COMPLEX: SWAP(data[n], data[m])
+                // Real Part
+                tempr = data[n];
+                data[n] = data[m];
+                data[m] = tempr;
+                // Imagery Part
+                n++;
+                m++;
+                tempi = data[n];
+                data[n] = data[m];
+                data[m] = tempi;
+            }
+
+            // Performing Bit-Reversal, odd v.s. even, O(N)
+
+            int m = j + fftFrameSize; // bitm_array[i+2];
+            // COMPLEX: SWAP(data[n], data[m])
+            // Real Part
+            int n = i + 2;
+            double tempr = data[n];
+            data[n] = data[m];
+            data[m] = tempr;
+            // Imagery Part
+            n++;
+            m++;
+            double tempi = data[n];
+            data[n] = data[m];
+            data[m] = tempi;
+        }
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/InvalidDataException.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,45 +1,45 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-
-/**
- * This exception is used when a file contains illegal or unexpected data.
- *
- * @author Karl Helgason
- */
-public class InvalidDataException extends IOException {
-
-    private static final long serialVersionUID = 1L;
-
-    public InvalidDataException() {
-        super("Invalid Data!");
-    }
-
-    public InvalidDataException(String s) {
-        super(s);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+
+/**
+ * This exception is used when a file contains illegal or unexpected data.
+ *
+ * @author Karl Helgason
+ */
+public class InvalidDataException extends IOException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InvalidDataException() {
+        super("Invalid Data!");
+    }
+
+    public InvalidDataException(String s) {
+        super(s);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/InvalidFormatException.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,44 +1,44 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This exception is used when a reader is used to read file of a format
- * it doesn't unterstand or support.
- *
- * @author Karl Helgason
- */
-public class InvalidFormatException extends InvalidDataException {
-
-    private static final long serialVersionUID = 1L;
-
-    public InvalidFormatException() {
-        super("Invalid format!");
-    }
-
-    public InvalidFormatException(String s) {
-        super(s);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This exception is used when a reader is used to read file of a format
+ * it doesn't unterstand or support.
+ *
+ * @author Karl Helgason
+ */
+public class InvalidFormatException extends InvalidDataException {
+
+    private static final long serialVersionUID = 1L;
+
+    public InvalidFormatException() {
+        super("Invalid format!");
+    }
+
+    public InvalidFormatException(String s) {
+        super(s);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/JARSoundbankReader.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,113 +1,113 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.spi.SoundbankReader;
-
-/**
- * JarSoundbankReader is used to read sounbank object from jar files.
- *
- * @author Karl Helgason
- */
-public class JARSoundbankReader extends SoundbankReader {
-
-    public boolean isZIP(URL url) {
-        boolean ok = false;
-        try {
-            InputStream stream = url.openStream();
-            try {
-                byte[] buff = new byte[4];
-                ok = stream.read(buff) == 4;
-                if (ok) {
-                    ok =  (buff[0] == 0x50
-                        && buff[1] == 0x4b
-                        && buff[2] == 0x03
-                        && buff[3] == 0x04);
-                }
-            } finally {
-                stream.close();
-            }
-        } catch (IOException e) {
-        }
-        return ok;
-    }
-
-    public Soundbank getSoundbank(URL url)
-            throws InvalidMidiDataException, IOException {
-        if (!isZIP(url))
-            return null;
-        ArrayList<Soundbank> soundbanks = new ArrayList<Soundbank>();
-        URLClassLoader ucl = URLClassLoader.newInstance(new URL[]{url});
-        InputStream stream = ucl.getResourceAsStream(
-                "META-INF/services/javax.sound.midi.Soundbank");
-        if (stream == null)
-            return null;
-        BufferedReader r = new BufferedReader(new InputStreamReader(stream));
-        String line = r.readLine();
-        while (line != null) {
-            if (!line.startsWith("#")) {
-                try {
-                    Class c = Class.forName(line.trim(), true, ucl);
-                    Object o = c.newInstance();
-                    if (o instanceof Soundbank) {
-                        soundbanks.add((Soundbank) o);
-                    }
-                } catch (Exception e) {
-                    //e.printStackTrace();
-                }
-            }
-            line = r.readLine();
-        }
-        stream.close();
-        if (soundbanks.size() == 0)
-            return null;
-        if (soundbanks.size() == 1)
-            return soundbanks.get(0);
-        SimpleSoundbank sbk = new SimpleSoundbank();
-        for (Soundbank soundbank : soundbanks)
-            sbk.addAllInstruments(soundbank);
-        return sbk;
-    }
-
-    public Soundbank getSoundbank(InputStream stream)
-            throws InvalidMidiDataException, IOException {
-        return null;
-    }
-
-    public Soundbank getSoundbank(File file)
-            throws InvalidMidiDataException, IOException {
-        return getSoundbank(file.toURI().toURL());
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * JarSoundbankReader is used to read sounbank object from jar files.
+ *
+ * @author Karl Helgason
+ */
+public class JARSoundbankReader extends SoundbankReader {
+
+    public boolean isZIP(URL url) {
+        boolean ok = false;
+        try {
+            InputStream stream = url.openStream();
+            try {
+                byte[] buff = new byte[4];
+                ok = stream.read(buff) == 4;
+                if (ok) {
+                    ok =  (buff[0] == 0x50
+                        && buff[1] == 0x4b
+                        && buff[2] == 0x03
+                        && buff[3] == 0x04);
+                }
+            } finally {
+                stream.close();
+            }
+        } catch (IOException e) {
+        }
+        return ok;
+    }
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        if (!isZIP(url))
+            return null;
+        ArrayList<Soundbank> soundbanks = new ArrayList<Soundbank>();
+        URLClassLoader ucl = URLClassLoader.newInstance(new URL[]{url});
+        InputStream stream = ucl.getResourceAsStream(
+                "META-INF/services/javax.sound.midi.Soundbank");
+        if (stream == null)
+            return null;
+        BufferedReader r = new BufferedReader(new InputStreamReader(stream));
+        String line = r.readLine();
+        while (line != null) {
+            if (!line.startsWith("#")) {
+                try {
+                    Class c = Class.forName(line.trim(), true, ucl);
+                    Object o = c.newInstance();
+                    if (o instanceof Soundbank) {
+                        soundbanks.add((Soundbank) o);
+                    }
+                } catch (Exception e) {
+                    //e.printStackTrace();
+                }
+            }
+            line = r.readLine();
+        }
+        stream.close();
+        if (soundbanks.size() == 0)
+            return null;
+        if (soundbanks.size() == 1)
+            return soundbanks.get(0);
+        SimpleSoundbank sbk = new SimpleSoundbank();
+        for (Soundbank soundbank : soundbanks)
+            sbk.addAllInstruments(soundbank);
+        return sbk;
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        return null;
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        return getSoundbank(file.toURI().toURL());
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractChannelMixer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,126 +1,126 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * ModelAbstractChannelMixer is ready for use class to implement
- * ModelChannelMixer interface.
- *
- * @author Karl Helgason
- */
-public abstract class ModelAbstractChannelMixer implements ModelChannelMixer {
-
-    public abstract boolean process(float[][] buffer, int offset, int len);
-
-    public abstract void stop();
-
-    public void allNotesOff() {
-    }
-
-    public void allSoundOff() {
-    }
-
-    public void controlChange(int controller, int value) {
-    }
-
-    public int getChannelPressure() {
-        return 0;
-    }
-
-    public int getController(int controller) {
-        return 0;
-    }
-
-    public boolean getMono() {
-        return false;
-    }
-
-    public boolean getMute() {
-        return false;
-    }
-
-    public boolean getOmni() {
-        return false;
-    }
-
-    public int getPitchBend() {
-        return 0;
-    }
-
-    public int getPolyPressure(int noteNumber) {
-        return 0;
-    }
-
-    public int getProgram() {
-        return 0;
-    }
-
-    public boolean getSolo() {
-        return false;
-    }
-
-    public boolean localControl(boolean on) {
-        return false;
-    }
-
-    public void noteOff(int noteNumber) {
-    }
-
-    public void noteOff(int noteNumber, int velocity) {
-    }
-
-    public void noteOn(int noteNumber, int velocity) {
-    }
-
-    public void programChange(int program) {
-    }
-
-    public void programChange(int bank, int program) {
-    }
-
-    public void resetAllControllers() {
-    }
-
-    public void setChannelPressure(int pressure) {
-    }
-
-    public void setMono(boolean on) {
-    }
-
-    public void setMute(boolean mute) {
-    }
-
-    public void setOmni(boolean on) {
-    }
-
-    public void setPitchBend(int bend) {
-    }
-
-    public void setPolyPressure(int noteNumber, int pressure) {
-    }
-
-    public void setSolo(boolean soloState) {
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * ModelAbstractChannelMixer is ready for use class to implement
+ * ModelChannelMixer interface.
+ *
+ * @author Karl Helgason
+ */
+public abstract class ModelAbstractChannelMixer implements ModelChannelMixer {
+
+    public abstract boolean process(float[][] buffer, int offset, int len);
+
+    public abstract void stop();
+
+    public void allNotesOff() {
+    }
+
+    public void allSoundOff() {
+    }
+
+    public void controlChange(int controller, int value) {
+    }
+
+    public int getChannelPressure() {
+        return 0;
+    }
+
+    public int getController(int controller) {
+        return 0;
+    }
+
+    public boolean getMono() {
+        return false;
+    }
+
+    public boolean getMute() {
+        return false;
+    }
+
+    public boolean getOmni() {
+        return false;
+    }
+
+    public int getPitchBend() {
+        return 0;
+    }
+
+    public int getPolyPressure(int noteNumber) {
+        return 0;
+    }
+
+    public int getProgram() {
+        return 0;
+    }
+
+    public boolean getSolo() {
+        return false;
+    }
+
+    public boolean localControl(boolean on) {
+        return false;
+    }
+
+    public void noteOff(int noteNumber) {
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+    }
+
+    public void programChange(int program) {
+    }
+
+    public void programChange(int bank, int program) {
+    }
+
+    public void resetAllControllers() {
+    }
+
+    public void setChannelPressure(int pressure) {
+    }
+
+    public void setMono(boolean on) {
+    }
+
+    public void setMute(boolean mute) {
+    }
+
+    public void setOmni(boolean on) {
+    }
+
+    public void setPitchBend(int bend) {
+    }
+
+    public void setPolyPressure(int noteNumber, int pressure) {
+    }
+
+    public void setSolo(boolean soloState) {
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelAbstractOscillator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,200 +1,200 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import javax.sound.midi.Instrument;
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.Patch;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.SoundbankResource;
-import javax.sound.midi.VoiceStatus;
-
-/**
- * A abstract class used to simplify creating custom ModelOscillator.
- *
- * @author Karl Helgason
- */
-public abstract class ModelAbstractOscillator
-        implements ModelOscillator, ModelOscillatorStream, Soundbank {
-
-    protected float pitch = 6000;
-    protected float samplerate;
-    protected MidiChannel channel;
-    protected VoiceStatus voice;
-    protected int noteNumber;
-    protected int velocity;
-    protected boolean on = false;
-
-    public void init() {
-    }
-
-    public void close() throws IOException {
-    }
-
-    public void noteOff(int velocity) {
-        on = false;
-    }
-
-    public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber,
-            int velocity) {
-        this.channel = channel;
-        this.voice = voice;
-        this.noteNumber = noteNumber;
-        this.velocity = velocity;
-        on = true;
-    }
-
-    public int read(float[][] buffer, int offset, int len) throws IOException {
-        return -1;
-    }
-
-    public MidiChannel getChannel() {
-        return channel;
-    }
-
-    public VoiceStatus getVoice() {
-        return voice;
-    }
-
-    public int getNoteNumber() {
-        return noteNumber;
-    }
-
-    public int getVelocity() {
-        return velocity;
-    }
-
-    public boolean isOn() {
-        return on;
-    }
-
-    public void setPitch(float pitch) {
-        this.pitch = pitch;
-    }
-
-    public float getPitch() {
-        return pitch;
-    }
-
-    public void setSampleRate(float samplerate) {
-        this.samplerate = samplerate;
-    }
-
-    public float getSampleRate() {
-        return samplerate;
-    }
-
-    public float getAttenuation() {
-        return 0;
-    }
-
-    public int getChannels() {
-        return 1;
-    }
-
-    public String getName() {
-        return getClass().getName();
-    }
-
-    public Patch getPatch() {
-        return new Patch(0, 0);
-    }
-
-    public ModelOscillatorStream open(float samplerate) {
-        ModelAbstractOscillator oscs;
-        try {
-            oscs = this.getClass().newInstance();
-        } catch (InstantiationException e) {
-            throw new IllegalArgumentException(e);
-        } catch (IllegalAccessException e) {
-            throw new IllegalArgumentException(e);
-        }
-        oscs.setSampleRate(samplerate);
-        oscs.init();
-        return oscs;
-    }
-
-    public ModelPerformer getPerformer() {
-        // Create performer for my custom oscillirator
-        ModelPerformer performer = new ModelPerformer();
-        performer.getOscillators().add(this);
-        return performer;
-
-    }
-
-    public ModelInstrument getInstrument() {
-        // Create Instrument object around my performer
-        SimpleInstrument ins = new SimpleInstrument();
-        ins.setName(getName());
-        ins.add(getPerformer());
-        ins.setPatch(getPatch());
-        return ins;
-
-    }
-
-    public Soundbank getSoundBank() {
-        // Create Soundbank object around the instrument
-        SimpleSoundbank sbk = new SimpleSoundbank();
-        sbk.addInstrument(getInstrument());
-        return sbk;
-    }
-
-    public String getDescription() {
-        return getName();
-    }
-
-    public Instrument getInstrument(Patch patch) {
-        Instrument ins = getInstrument();
-        Patch p = ins.getPatch();
-        if (p.getBank() != patch.getBank())
-            return null;
-        if (p.getProgram() != patch.getProgram())
-            return null;
-        if (p instanceof ModelPatch && patch instanceof ModelPatch) {
-            if (((ModelPatch)p).isPercussion()
-                    != ((ModelPatch)patch).isPercussion()) {
-                return null;
-            }
-        }
-        return ins;
-    }
-
-    public Instrument[] getInstruments() {
-        return new Instrument[]{getInstrument()};
-    }
-
-    public SoundbankResource[] getResources() {
-        return new SoundbankResource[0];
-    }
-
-    public String getVendor() {
-        return null;
-    }
-
-    public String getVersion() {
-        return null;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * A abstract class used to simplify creating custom ModelOscillator.
+ *
+ * @author Karl Helgason
+ */
+public abstract class ModelAbstractOscillator
+        implements ModelOscillator, ModelOscillatorStream, Soundbank {
+
+    protected float pitch = 6000;
+    protected float samplerate;
+    protected MidiChannel channel;
+    protected VoiceStatus voice;
+    protected int noteNumber;
+    protected int velocity;
+    protected boolean on = false;
+
+    public void init() {
+    }
+
+    public void close() throws IOException {
+    }
+
+    public void noteOff(int velocity) {
+        on = false;
+    }
+
+    public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber,
+            int velocity) {
+        this.channel = channel;
+        this.voice = voice;
+        this.noteNumber = noteNumber;
+        this.velocity = velocity;
+        on = true;
+    }
+
+    public int read(float[][] buffer, int offset, int len) throws IOException {
+        return -1;
+    }
+
+    public MidiChannel getChannel() {
+        return channel;
+    }
+
+    public VoiceStatus getVoice() {
+        return voice;
+    }
+
+    public int getNoteNumber() {
+        return noteNumber;
+    }
+
+    public int getVelocity() {
+        return velocity;
+    }
+
+    public boolean isOn() {
+        return on;
+    }
+
+    public void setPitch(float pitch) {
+        this.pitch = pitch;
+    }
+
+    public float getPitch() {
+        return pitch;
+    }
+
+    public void setSampleRate(float samplerate) {
+        this.samplerate = samplerate;
+    }
+
+    public float getSampleRate() {
+        return samplerate;
+    }
+
+    public float getAttenuation() {
+        return 0;
+    }
+
+    public int getChannels() {
+        return 1;
+    }
+
+    public String getName() {
+        return getClass().getName();
+    }
+
+    public Patch getPatch() {
+        return new Patch(0, 0);
+    }
+
+    public ModelOscillatorStream open(float samplerate) {
+        ModelAbstractOscillator oscs;
+        try {
+            oscs = this.getClass().newInstance();
+        } catch (InstantiationException e) {
+            throw new IllegalArgumentException(e);
+        } catch (IllegalAccessException e) {
+            throw new IllegalArgumentException(e);
+        }
+        oscs.setSampleRate(samplerate);
+        oscs.init();
+        return oscs;
+    }
+
+    public ModelPerformer getPerformer() {
+        // Create performer for my custom oscillirator
+        ModelPerformer performer = new ModelPerformer();
+        performer.getOscillators().add(this);
+        return performer;
+
+    }
+
+    public ModelInstrument getInstrument() {
+        // Create Instrument object around my performer
+        SimpleInstrument ins = new SimpleInstrument();
+        ins.setName(getName());
+        ins.add(getPerformer());
+        ins.setPatch(getPatch());
+        return ins;
+
+    }
+
+    public Soundbank getSoundBank() {
+        // Create Soundbank object around the instrument
+        SimpleSoundbank sbk = new SimpleSoundbank();
+        sbk.addInstrument(getInstrument());
+        return sbk;
+    }
+
+    public String getDescription() {
+        return getName();
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        Instrument ins = getInstrument();
+        Patch p = ins.getPatch();
+        if (p.getBank() != patch.getBank())
+            return null;
+        if (p.getProgram() != patch.getProgram())
+            return null;
+        if (p instanceof ModelPatch && patch instanceof ModelPatch) {
+            if (((ModelPatch)p).isPercussion()
+                    != ((ModelPatch)patch).isPercussion()) {
+                return null;
+            }
+        }
+        return ins;
+    }
+
+    public Instrument[] getInstruments() {
+        return new Instrument[]{getInstrument()};
+    }
+
+    public SoundbankResource[] getResources() {
+        return new SoundbankResource[0];
+    }
+
+    public String getVendor() {
+        return null;
+    }
+
+    public String getVersion() {
+        return null;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelByteBuffer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,326 +1,326 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-import java.util.Collection;
-
-/**
- * This class is a pointer to a binary array either in memory or on disk.
- *
- * @author Karl Helgason
- */
-public class ModelByteBuffer {
-
-    private ModelByteBuffer root = this;
-    private File file;
-    private long fileoffset;
-    private byte[] buffer;
-    private long offset;
-    private long len;
-
-    private class RandomFileInputStream extends InputStream {
-
-        private RandomAccessFile raf;
-        private long left;
-        private long mark = 0;
-        private long markleft = 0;
-
-        public RandomFileInputStream() throws IOException {
-            raf = new RandomAccessFile(root.file, "r");
-            raf.seek(root.fileoffset + arrayOffset());
-            left = capacity();
-        }
-
-        public int available() throws IOException {
-            if (left > Integer.MAX_VALUE)
-                return Integer.MAX_VALUE;
-            return (int)left;
-        }
-
-        public synchronized void mark(int readlimit) {
-            try {
-                mark = raf.getFilePointer();
-                markleft = left;
-            } catch (IOException e) {
-                //e.printStackTrace();
-            }
-        }
-
-        public boolean markSupported() {
-            return true;
-        }
-
-        public synchronized void reset() throws IOException {
-            raf.seek(mark);
-            left = markleft;
-        }
-
-        public long skip(long n) throws IOException {
-            if (n > left)
-                n = left;
-            n = super.skip(n);
-            if (n == -1)
-                return -1;
-            left -= n;
-            return n;
-        }
-
-        public int read(byte b[], int off, int len) throws IOException {
-            if (len > left)
-                len = (int)left;
-            if (left == 0)
-                return -1;
-            len = raf.read(b, off, len);
-            if (len == -1)
-                return -1;
-            left -= len;
-            return len;
-        }
-
-        public int read(byte[] b) throws IOException {
-            if (len > left)
-                len = (int)left;
-            if (left == 0)
-                return -1;
-            int len = raf.read(b);
-            if (len == -1)
-                return -1;
-            left -= len;
-            return len;
-        }
-
-        public int read() throws IOException {
-            if (len == 0)
-                return -1;
-            int b = raf.read();
-            if (b == -1)
-                return -1;
-            len--;
-            return b;
-        }
-
-        public void close() throws IOException {
-            raf.close();
-        }
-    }
-
-    private ModelByteBuffer(ModelByteBuffer parent,
-            long beginIndex, long endIndex, boolean independent) {
-        this.root = parent.root;
-        this.offset = 0;
-        this.len = parent.len;
-        if (beginIndex < 0)
-            beginIndex = 0;
-        if (beginIndex > len)
-            beginIndex = len;
-        if (endIndex < 0)
-            endIndex = 0;
-        if (endIndex > len)
-            endIndex = len;
-        if (beginIndex > endIndex)
-            beginIndex = endIndex;
-        offset = beginIndex;
-        len = endIndex - beginIndex;
-        if (independent) {
-            buffer = root.buffer;
-            if (root.file != null) {
-                file = root.file;
-                fileoffset = root.fileoffset + arrayOffset();
-                offset = 0;
-            } else
-                offset = arrayOffset();
-            root = this;
-        }
-    }
-
-    public ModelByteBuffer(byte[] buffer) {
-        this.buffer = buffer;
-        this.offset = 0;
-        this.len = buffer.length;
-    }
-
-    public ModelByteBuffer(byte[] buffer, int offset, int len) {
-        this.buffer = buffer;
-        this.offset = offset;
-        this.len = len;
-    }
-
-    public ModelByteBuffer(File file) {
-        this.file = file;
-        this.fileoffset = 0;
-        this.len = file.length();
-    }
-
-    public ModelByteBuffer(File file, long offset, long len) {
-        this.file = file;
-        this.fileoffset = offset;
-        this.len = len;
-    }
-
-    public void writeTo(OutputStream out) throws IOException {
-        if (root.file != null && root.buffer == null) {
-            InputStream is = getInputStream();
-            byte[] buff = new byte[1024];
-            int ret;
-            while ((ret = is.read(buff)) != -1)
-                out.write(buff, 0, ret);
-        } else
-            out.write(array(), (int) arrayOffset(), (int) capacity());
-    }
-
-    public InputStream getInputStream() {
-        if (root.file != null && root.buffer == null) {
-            try {
-                return new RandomFileInputStream();
-            } catch (IOException e) {
-                //e.printStackTrace();
-                return null;
-            }
-        }
-        return new ByteArrayInputStream(array(),
-                (int)arrayOffset(), (int)capacity());
-    }
-
-    public ModelByteBuffer subbuffer(long beginIndex) {
-        return subbuffer(beginIndex, capacity());
-    }
-
-    public ModelByteBuffer subbuffer(long beginIndex, long endIndex) {
-        return subbuffer(beginIndex, endIndex, false);
-    }
-
-    public ModelByteBuffer subbuffer(long beginIndex, long endIndex,
-            boolean independent) {
-        return new ModelByteBuffer(this, beginIndex, endIndex, independent);
-    }
-
-    public byte[] array() {
-        return root.buffer;
-    }
-
-    public long arrayOffset() {
-        if (root != this)
-            return root.arrayOffset() + offset;
-        return offset;
-    }
-
-    public long capacity() {
-        return len;
-    }
-
-    public ModelByteBuffer getRoot() {
-        return root;
-    }
-
-    public File getFile() {
-        return file;
-    }
-
-    public long getFilePointer() {
-        return fileoffset;
-    }
-
-    public static void loadAll(Collection<ModelByteBuffer> col)
-            throws IOException {
-        File selfile = null;
-        RandomAccessFile raf = null;
-        try {
-            for (ModelByteBuffer mbuff : col) {
-                mbuff = mbuff.root;
-                if (mbuff.file == null)
-                    continue;
-                if (mbuff.buffer != null)
-                    continue;
-                if (selfile == null || !selfile.equals(mbuff.file)) {
-                    if (raf != null) {
-                        raf.close();
-                        raf = null;
-                    }
-                    selfile = mbuff.file;
-                    raf = new RandomAccessFile(mbuff.file, "r");
-                }
-                raf.seek(mbuff.fileoffset);
-                byte[] buffer = new byte[(int) mbuff.capacity()];
-
-                int read = 0;
-                int avail = buffer.length;
-                while (read != avail) {
-                    if (avail - read > 65536) {
-                        raf.read(buffer, read, 65536);
-                        read += 65536;
-                    } else {
-                        raf.read(buffer, read, avail - read);
-                        read = avail;
-                    }
-
-                }
-
-                mbuff.buffer = buffer;
-                mbuff.offset = 0;
-            }
-        } finally {
-            if (raf != null)
-                raf.close();
-        }
-    }
-
-    public void load() throws IOException {
-        if (root != this) {
-            root.load();
-            return;
-        }
-        if (buffer != null)
-            return;
-        if (file == null) {
-            throw new IllegalStateException(
-                    "No file associated with this ByteBuffer!");
-        }
-
-        InputStream is = getInputStream();
-        buffer = new byte[(int) capacity()];
-        offset = 0;
-        is.read(buffer);
-        is.close();
-
-    }
-
-    public void unload() {
-        if (root != this) {
-            root.unload();
-            return;
-        }
-        if (file == null) {
-            throw new IllegalStateException(
-                    "No file associated with this ByteBuffer!");
-        }
-        root.buffer = null;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.util.Collection;
+
+/**
+ * This class is a pointer to a binary array either in memory or on disk.
+ *
+ * @author Karl Helgason
+ */
+public class ModelByteBuffer {
+
+    private ModelByteBuffer root = this;
+    private File file;
+    private long fileoffset;
+    private byte[] buffer;
+    private long offset;
+    private long len;
+
+    private class RandomFileInputStream extends InputStream {
+
+        private RandomAccessFile raf;
+        private long left;
+        private long mark = 0;
+        private long markleft = 0;
+
+        public RandomFileInputStream() throws IOException {
+            raf = new RandomAccessFile(root.file, "r");
+            raf.seek(root.fileoffset + arrayOffset());
+            left = capacity();
+        }
+
+        public int available() throws IOException {
+            if (left > Integer.MAX_VALUE)
+                return Integer.MAX_VALUE;
+            return (int)left;
+        }
+
+        public synchronized void mark(int readlimit) {
+            try {
+                mark = raf.getFilePointer();
+                markleft = left;
+            } catch (IOException e) {
+                //e.printStackTrace();
+            }
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public synchronized void reset() throws IOException {
+            raf.seek(mark);
+            left = markleft;
+        }
+
+        public long skip(long n) throws IOException {
+            if (n > left)
+                n = left;
+            n = super.skip(n);
+            if (n == -1)
+                return -1;
+            left -= n;
+            return n;
+        }
+
+        public int read(byte b[], int off, int len) throws IOException {
+            if (len > left)
+                len = (int)left;
+            if (left == 0)
+                return -1;
+            len = raf.read(b, off, len);
+            if (len == -1)
+                return -1;
+            left -= len;
+            return len;
+        }
+
+        public int read(byte[] b) throws IOException {
+            if (len > left)
+                len = (int)left;
+            if (left == 0)
+                return -1;
+            int len = raf.read(b);
+            if (len == -1)
+                return -1;
+            left -= len;
+            return len;
+        }
+
+        public int read() throws IOException {
+            if (len == 0)
+                return -1;
+            int b = raf.read();
+            if (b == -1)
+                return -1;
+            len--;
+            return b;
+        }
+
+        public void close() throws IOException {
+            raf.close();
+        }
+    }
+
+    private ModelByteBuffer(ModelByteBuffer parent,
+            long beginIndex, long endIndex, boolean independent) {
+        this.root = parent.root;
+        this.offset = 0;
+        this.len = parent.len;
+        if (beginIndex < 0)
+            beginIndex = 0;
+        if (beginIndex > len)
+            beginIndex = len;
+        if (endIndex < 0)
+            endIndex = 0;
+        if (endIndex > len)
+            endIndex = len;
+        if (beginIndex > endIndex)
+            beginIndex = endIndex;
+        offset = beginIndex;
+        len = endIndex - beginIndex;
+        if (independent) {
+            buffer = root.buffer;
+            if (root.file != null) {
+                file = root.file;
+                fileoffset = root.fileoffset + arrayOffset();
+                offset = 0;
+            } else
+                offset = arrayOffset();
+            root = this;
+        }
+    }
+
+    public ModelByteBuffer(byte[] buffer) {
+        this.buffer = buffer;
+        this.offset = 0;
+        this.len = buffer.length;
+    }
+
+    public ModelByteBuffer(byte[] buffer, int offset, int len) {
+        this.buffer = buffer;
+        this.offset = offset;
+        this.len = len;
+    }
+
+    public ModelByteBuffer(File file) {
+        this.file = file;
+        this.fileoffset = 0;
+        this.len = file.length();
+    }
+
+    public ModelByteBuffer(File file, long offset, long len) {
+        this.file = file;
+        this.fileoffset = offset;
+        this.len = len;
+    }
+
+    public void writeTo(OutputStream out) throws IOException {
+        if (root.file != null && root.buffer == null) {
+            InputStream is = getInputStream();
+            byte[] buff = new byte[1024];
+            int ret;
+            while ((ret = is.read(buff)) != -1)
+                out.write(buff, 0, ret);
+        } else
+            out.write(array(), (int) arrayOffset(), (int) capacity());
+    }
+
+    public InputStream getInputStream() {
+        if (root.file != null && root.buffer == null) {
+            try {
+                return new RandomFileInputStream();
+            } catch (IOException e) {
+                //e.printStackTrace();
+                return null;
+            }
+        }
+        return new ByteArrayInputStream(array(),
+                (int)arrayOffset(), (int)capacity());
+    }
+
+    public ModelByteBuffer subbuffer(long beginIndex) {
+        return subbuffer(beginIndex, capacity());
+    }
+
+    public ModelByteBuffer subbuffer(long beginIndex, long endIndex) {
+        return subbuffer(beginIndex, endIndex, false);
+    }
+
+    public ModelByteBuffer subbuffer(long beginIndex, long endIndex,
+            boolean independent) {
+        return new ModelByteBuffer(this, beginIndex, endIndex, independent);
+    }
+
+    public byte[] array() {
+        return root.buffer;
+    }
+
+    public long arrayOffset() {
+        if (root != this)
+            return root.arrayOffset() + offset;
+        return offset;
+    }
+
+    public long capacity() {
+        return len;
+    }
+
+    public ModelByteBuffer getRoot() {
+        return root;
+    }
+
+    public File getFile() {
+        return file;
+    }
+
+    public long getFilePointer() {
+        return fileoffset;
+    }
+
+    public static void loadAll(Collection<ModelByteBuffer> col)
+            throws IOException {
+        File selfile = null;
+        RandomAccessFile raf = null;
+        try {
+            for (ModelByteBuffer mbuff : col) {
+                mbuff = mbuff.root;
+                if (mbuff.file == null)
+                    continue;
+                if (mbuff.buffer != null)
+                    continue;
+                if (selfile == null || !selfile.equals(mbuff.file)) {
+                    if (raf != null) {
+                        raf.close();
+                        raf = null;
+                    }
+                    selfile = mbuff.file;
+                    raf = new RandomAccessFile(mbuff.file, "r");
+                }
+                raf.seek(mbuff.fileoffset);
+                byte[] buffer = new byte[(int) mbuff.capacity()];
+
+                int read = 0;
+                int avail = buffer.length;
+                while (read != avail) {
+                    if (avail - read > 65536) {
+                        raf.read(buffer, read, 65536);
+                        read += 65536;
+                    } else {
+                        raf.read(buffer, read, avail - read);
+                        read = avail;
+                    }
+
+                }
+
+                mbuff.buffer = buffer;
+                mbuff.offset = 0;
+            }
+        } finally {
+            if (raf != null)
+                raf.close();
+        }
+    }
+
+    public void load() throws IOException {
+        if (root != this) {
+            root.load();
+            return;
+        }
+        if (buffer != null)
+            return;
+        if (file == null) {
+            throw new IllegalStateException(
+                    "No file associated with this ByteBuffer!");
+        }
+
+        InputStream is = getInputStream();
+        buffer = new byte[(int) capacity()];
+        offset = 0;
+        is.read(buffer);
+        is.close();
+
+    }
+
+    public void unload() {
+        if (root != this) {
+            root.unload();
+            return;
+        }
+        if (file == null) {
+            throw new IllegalStateException(
+                    "No file associated with this ByteBuffer!");
+        }
+        root.buffer = null;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelByteBufferWavetable.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,281 +1,281 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import java.io.InputStream;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.AudioFormat.Encoding;
-
-/**
- * Wavetable oscillator for pre-loaded data.
- *
- * @author Karl Helgason
- */
-public class ModelByteBufferWavetable implements ModelWavetable {
-
-    private class Buffer8PlusInputStream extends InputStream {
-
-        private boolean bigendian;
-        private int framesize_pc;
-        int pos = 0;
-        int pos2 = 0;
-        int markpos = 0;
-        int markpos2 = 0;
-
-        public Buffer8PlusInputStream() {
-            framesize_pc = format.getFrameSize() / format.getChannels();
-            bigendian = format.isBigEndian();
-        }
-
-        public int read(byte[] b, int off, int len) throws IOException {
-            int avail = available();
-            if (avail <= 0)
-                return -1;
-            if (len > avail)
-                len = avail;
-            byte[] buff1 = buffer.array();
-            byte[] buff2 = buffer8.array();
-            pos += buffer.arrayOffset();
-            pos2 += buffer8.arrayOffset();
-            if (bigendian) {
-                for (int i = 0; i < len; i += (framesize_pc + 1)) {
-                    System.arraycopy(buff1, pos, b, i, framesize_pc);
-                    System.arraycopy(buff2, pos2, b, i + framesize_pc, 1);
-                    pos += framesize_pc;
-                    pos2 += 1;
-                }
-            } else {
-                for (int i = 0; i < len; i += (framesize_pc + 1)) {
-                    System.arraycopy(buff2, pos2, b, i, 1);
-                    System.arraycopy(buff1, pos, b, i + 1, framesize_pc);
-                    pos += framesize_pc;
-                    pos2 += 1;
-                }
-            }
-            pos -= buffer.arrayOffset();
-            pos2 -= buffer8.arrayOffset();
-            return len;
-        }
-
-        public long skip(long n) throws IOException {
-            int avail = available();
-            if (avail <= 0)
-                return -1;
-            if (n > avail)
-                n = avail;
-            pos += (n / (framesize_pc + 1)) * (framesize_pc);
-            pos2 += n / (framesize_pc + 1);
-            return super.skip(n);
-        }
-
-        public int read(byte[] b) throws IOException {
-            return read(b, 0, b.length);
-        }
-
-        public int read() throws IOException {
-            byte[] b = new byte[1];
-            int ret = read(b, 0, 1);
-            if (ret == -1)
-                return -1;
-            return 0 & 0xFF;
-        }
-
-        public boolean markSupported() {
-            return true;
-        }
-
-        public int available() throws IOException {
-            return (int)buffer.capacity() + (int)buffer8.capacity() - pos - pos2;
-        }
-
-        public synchronized void mark(int readlimit) {
-            markpos = pos;
-            markpos2 = pos2;
-        }
-
-        public synchronized void reset() throws IOException {
-            pos = markpos;
-            pos2 = markpos2;
-
-        }
-    }
-
-    private float loopStart = -1;
-    private float loopLength = -1;
-    private ModelByteBuffer buffer;
-    private ModelByteBuffer buffer8 = null;
-    private AudioFormat format = null;
-    private float pitchcorrection = 0;
-    private float attenuation = 0;
-    private int loopType = LOOP_TYPE_OFF;
-
-    public ModelByteBufferWavetable(ModelByteBuffer buffer) {
-        this.buffer = buffer;
-    }
-
-    public ModelByteBufferWavetable(ModelByteBuffer buffer,
-            float pitchcorrection) {
-        this.buffer = buffer;
-        this.pitchcorrection = pitchcorrection;
-    }
-
-    public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format) {
-        this.format = format;
-        this.buffer = buffer;
-    }
-
-    public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format,
-            float pitchcorrection) {
-        this.format = format;
-        this.buffer = buffer;
-        this.pitchcorrection = pitchcorrection;
-    }
-
-    public void set8BitExtensionBuffer(ModelByteBuffer buffer) {
-        buffer8 = buffer;
-    }
-
-    public ModelByteBuffer get8BitExtensionBuffer() {
-        return buffer8;
-    }
-
-    public ModelByteBuffer getBuffer() {
-        return buffer;
-    }
-
-    public AudioFormat getFormat() {
-        if (format == null) {
-            if (buffer == null)
-                return null;
-            InputStream is = buffer.getInputStream();
-            AudioFormat format = null;
-            try {
-                format = AudioSystem.getAudioFileFormat(is).getFormat();
-            } catch (Exception e) {
-                //e.printStackTrace();
-            }
-            try {
-                is.close();
-            } catch (IOException e) {
-                //e.printStackTrace();
-            }
-            return format;
-        }
-        return format;
-    }
-
-    public AudioFloatInputStream openStream() {
-        if (buffer == null)
-            return null;
-        if (format == null) {
-            InputStream is = buffer.getInputStream();
-            AudioInputStream ais = null;
-            try {
-                ais = AudioSystem.getAudioInputStream(is);
-            } catch (Exception e) {
-                //e.printStackTrace();
-                return null;
-            }
-            return AudioFloatInputStream.getInputStream(ais);
-        }
-        if (buffer.array() == null) {
-            return AudioFloatInputStream.getInputStream(new AudioInputStream(
-                    buffer.getInputStream(), format, buffer.capacity()));
-        }
-        if (buffer8 != null) {
-            if (format.getEncoding().equals(Encoding.PCM_SIGNED)
-                    || format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
-                InputStream is = new Buffer8PlusInputStream();
-                AudioFormat format2 = new AudioFormat(
-                        format.getEncoding(),
-                        format.getSampleRate(),
-                        format.getSampleSizeInBits() + 8,
-                        format.getChannels(),
-                        format.getFrameSize() + (1 * format.getChannels()),
-                        format.getFrameRate(),
-                        format.isBigEndian());
-
-                AudioInputStream ais = new AudioInputStream(is, format2,
-                        buffer.capacity() / format.getFrameSize());
-                return AudioFloatInputStream.getInputStream(ais);
-            }
-        }
-        return AudioFloatInputStream.getInputStream(format, buffer.array(),
-                (int)buffer.arrayOffset(), (int)buffer.capacity());
-    }
-
-    public int getChannels() {
-        return getFormat().getChannels();
-    }
-
-    public ModelOscillatorStream open(float samplerate) {
-        // ModelWavetableOscillator doesn't support ModelOscillatorStream
-        return null;
-    }
-
-    // attenuation is in cB
-    public float getAttenuation() {
-        return attenuation;
-    }
-    // attenuation is in cB
-    public void setAttenuation(float attenuation) {
-        this.attenuation = attenuation;
-    }
-
-    public float getLoopLength() {
-        return loopLength;
-    }
-
-    public void setLoopLength(float loopLength) {
-        this.loopLength = loopLength;
-    }
-
-    public float getLoopStart() {
-        return loopStart;
-    }
-
-    public void setLoopStart(float loopStart) {
-        this.loopStart = loopStart;
-    }
-
-    public void setLoopType(int loopType) {
-        this.loopType = loopType;
-    }
-
-    public int getLoopType() {
-        return loopType;
-    }
-
-    public float getPitchcorrection() {
-        return pitchcorrection;
-    }
-
-    public void setPitchcorrection(float pitchcorrection) {
-        this.pitchcorrection = pitchcorrection;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.AudioFormat.Encoding;
+
+/**
+ * Wavetable oscillator for pre-loaded data.
+ *
+ * @author Karl Helgason
+ */
+public class ModelByteBufferWavetable implements ModelWavetable {
+
+    private class Buffer8PlusInputStream extends InputStream {
+
+        private boolean bigendian;
+        private int framesize_pc;
+        int pos = 0;
+        int pos2 = 0;
+        int markpos = 0;
+        int markpos2 = 0;
+
+        public Buffer8PlusInputStream() {
+            framesize_pc = format.getFrameSize() / format.getChannels();
+            bigendian = format.isBigEndian();
+        }
+
+        public int read(byte[] b, int off, int len) throws IOException {
+            int avail = available();
+            if (avail <= 0)
+                return -1;
+            if (len > avail)
+                len = avail;
+            byte[] buff1 = buffer.array();
+            byte[] buff2 = buffer8.array();
+            pos += buffer.arrayOffset();
+            pos2 += buffer8.arrayOffset();
+            if (bigendian) {
+                for (int i = 0; i < len; i += (framesize_pc + 1)) {
+                    System.arraycopy(buff1, pos, b, i, framesize_pc);
+                    System.arraycopy(buff2, pos2, b, i + framesize_pc, 1);
+                    pos += framesize_pc;
+                    pos2 += 1;
+                }
+            } else {
+                for (int i = 0; i < len; i += (framesize_pc + 1)) {
+                    System.arraycopy(buff2, pos2, b, i, 1);
+                    System.arraycopy(buff1, pos, b, i + 1, framesize_pc);
+                    pos += framesize_pc;
+                    pos2 += 1;
+                }
+            }
+            pos -= buffer.arrayOffset();
+            pos2 -= buffer8.arrayOffset();
+            return len;
+        }
+
+        public long skip(long n) throws IOException {
+            int avail = available();
+            if (avail <= 0)
+                return -1;
+            if (n > avail)
+                n = avail;
+            pos += (n / (framesize_pc + 1)) * (framesize_pc);
+            pos2 += n / (framesize_pc + 1);
+            return super.skip(n);
+        }
+
+        public int read(byte[] b) throws IOException {
+            return read(b, 0, b.length);
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            int ret = read(b, 0, 1);
+            if (ret == -1)
+                return -1;
+            return 0 & 0xFF;
+        }
+
+        public boolean markSupported() {
+            return true;
+        }
+
+        public int available() throws IOException {
+            return (int)buffer.capacity() + (int)buffer8.capacity() - pos - pos2;
+        }
+
+        public synchronized void mark(int readlimit) {
+            markpos = pos;
+            markpos2 = pos2;
+        }
+
+        public synchronized void reset() throws IOException {
+            pos = markpos;
+            pos2 = markpos2;
+
+        }
+    }
+
+    private float loopStart = -1;
+    private float loopLength = -1;
+    private ModelByteBuffer buffer;
+    private ModelByteBuffer buffer8 = null;
+    private AudioFormat format = null;
+    private float pitchcorrection = 0;
+    private float attenuation = 0;
+    private int loopType = LOOP_TYPE_OFF;
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer) {
+        this.buffer = buffer;
+    }
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer,
+            float pitchcorrection) {
+        this.buffer = buffer;
+        this.pitchcorrection = pitchcorrection;
+    }
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format) {
+        this.format = format;
+        this.buffer = buffer;
+    }
+
+    public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format,
+            float pitchcorrection) {
+        this.format = format;
+        this.buffer = buffer;
+        this.pitchcorrection = pitchcorrection;
+    }
+
+    public void set8BitExtensionBuffer(ModelByteBuffer buffer) {
+        buffer8 = buffer;
+    }
+
+    public ModelByteBuffer get8BitExtensionBuffer() {
+        return buffer8;
+    }
+
+    public ModelByteBuffer getBuffer() {
+        return buffer;
+    }
+
+    public AudioFormat getFormat() {
+        if (format == null) {
+            if (buffer == null)
+                return null;
+            InputStream is = buffer.getInputStream();
+            AudioFormat format = null;
+            try {
+                format = AudioSystem.getAudioFileFormat(is).getFormat();
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+            try {
+                is.close();
+            } catch (IOException e) {
+                //e.printStackTrace();
+            }
+            return format;
+        }
+        return format;
+    }
+
+    public AudioFloatInputStream openStream() {
+        if (buffer == null)
+            return null;
+        if (format == null) {
+            InputStream is = buffer.getInputStream();
+            AudioInputStream ais = null;
+            try {
+                ais = AudioSystem.getAudioInputStream(is);
+            } catch (Exception e) {
+                //e.printStackTrace();
+                return null;
+            }
+            return AudioFloatInputStream.getInputStream(ais);
+        }
+        if (buffer.array() == null) {
+            return AudioFloatInputStream.getInputStream(new AudioInputStream(
+                    buffer.getInputStream(), format, buffer.capacity()));
+        }
+        if (buffer8 != null) {
+            if (format.getEncoding().equals(Encoding.PCM_SIGNED)
+                    || format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
+                InputStream is = new Buffer8PlusInputStream();
+                AudioFormat format2 = new AudioFormat(
+                        format.getEncoding(),
+                        format.getSampleRate(),
+                        format.getSampleSizeInBits() + 8,
+                        format.getChannels(),
+                        format.getFrameSize() + (1 * format.getChannels()),
+                        format.getFrameRate(),
+                        format.isBigEndian());
+
+                AudioInputStream ais = new AudioInputStream(is, format2,
+                        buffer.capacity() / format.getFrameSize());
+                return AudioFloatInputStream.getInputStream(ais);
+            }
+        }
+        return AudioFloatInputStream.getInputStream(format, buffer.array(),
+                (int)buffer.arrayOffset(), (int)buffer.capacity());
+    }
+
+    public int getChannels() {
+        return getFormat().getChannels();
+    }
+
+    public ModelOscillatorStream open(float samplerate) {
+        // ModelWavetableOscillator doesn't support ModelOscillatorStream
+        return null;
+    }
+
+    // attenuation is in cB
+    public float getAttenuation() {
+        return attenuation;
+    }
+    // attenuation is in cB
+    public void setAttenuation(float attenuation) {
+        this.attenuation = attenuation;
+    }
+
+    public float getLoopLength() {
+        return loopLength;
+    }
+
+    public void setLoopLength(float loopLength) {
+        this.loopLength = loopLength;
+    }
+
+    public float getLoopStart() {
+        return loopStart;
+    }
+
+    public void setLoopStart(float loopStart) {
+        this.loopStart = loopStart;
+    }
+
+    public void setLoopType(int loopType) {
+        this.loopType = loopType;
+    }
+
+    public int getLoopType() {
+        return loopType;
+    }
+
+    public float getPitchcorrection() {
+        return pitchcorrection;
+    }
+
+    public void setPitchcorrection(float pitchcorrection) {
+        this.pitchcorrection = pitchcorrection;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelChannelMixer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,50 +1,50 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.MidiChannel;
-
-/**
- * ModelChannelMixer is used to process channel voice mix output before going
- * to master output.<br>
- * It can be used to:<br>
- * <ul>
- *   <li>Implement non-voice oriented instruments.</li>
- *   <li>Add insert effect to instruments; for example distortion effect.</li>
- * </ui>
- * <p>
- * <b>Warning! Classes that implements ModelChannelMixer must be thread-safe.</b>
- *
- * @author Karl Helgason
- */
-public interface ModelChannelMixer extends MidiChannel {
-
-    // Used to process input audio from voices mix.
-    public boolean process(float[][] buffer, int offset, int len);
-
-    // Is used to trigger that this mixer is not be used
-    // and it should fade out.
-    public void stop();
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiChannel;
+
+/**
+ * ModelChannelMixer is used to process channel voice mix output before going
+ * to master output.<br>
+ * It can be used to:<br>
+ * <ul>
+ *   <li>Implement non-voice oriented instruments.</li>
+ *   <li>Add insert effect to instruments; for example distortion effect.</li>
+ * </ui>
+ * <p>
+ * <b>Warning! Classes that implements ModelChannelMixer must be thread-safe.</b>
+ *
+ * @author Karl Helgason
+ */
+public interface ModelChannelMixer extends MidiChannel {
+
+    // Used to process input audio from voices mix.
+    public boolean process(float[][] buffer, int offset, int len);
+
+    // Is used to trigger that this mixer is not be used
+    // and it should fade out.
+    public void stop();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelConnectionBlock.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelConnectionBlock.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,135 +1,135 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Connection blocks are used to connect source variable
- * to a destination variable.
- * For example Note On velocity can be connected to output gain.
- * In DLS this is called articulator and in SoundFonts (SF2) a modulator.
- *
- * @author Karl Helgason
- */
-public class ModelConnectionBlock {
-
-    //
-    //   source1 * source2 * scale -> destination
-    //
-    private final static ModelSource[] no_sources = new ModelSource[0];
-    private ModelSource[] sources = no_sources;
-    private double scale = 1;
-    private ModelDestination destination;
-
-    public ModelConnectionBlock() {
-    }
-
-    public ModelConnectionBlock(double scale, ModelDestination destination) {
-        this.scale = scale;
-        this.destination = destination;
-    }
-
-    public ModelConnectionBlock(ModelSource source,
-            ModelDestination destination) {
-        if (source != null) {
-            this.sources = new ModelSource[1];
-            this.sources[0] = source;
-        }
-        this.destination = destination;
-    }
-
-    public ModelConnectionBlock(ModelSource source, double scale,
-            ModelDestination destination) {
-        if (source != null) {
-            this.sources = new ModelSource[1];
-            this.sources[0] = source;
-        }
-        this.scale = scale;
-        this.destination = destination;
-    }
-
-    public ModelConnectionBlock(ModelSource source, ModelSource control,
-            ModelDestination destination) {
-        if (source != null) {
-            if (control == null) {
-                this.sources = new ModelSource[1];
-                this.sources[0] = source;
-            } else {
-                this.sources = new ModelSource[2];
-                this.sources[0] = source;
-                this.sources[1] = control;
-            }
-        }
-        this.destination = destination;
-    }
-
-    public ModelConnectionBlock(ModelSource source, ModelSource control,
-            double scale, ModelDestination destination) {
-        if (source != null) {
-            if (control == null) {
-                this.sources = new ModelSource[1];
-                this.sources[0] = source;
-            } else {
-                this.sources = new ModelSource[2];
-                this.sources[0] = source;
-                this.sources[1] = control;
-            }
-        }
-        this.scale = scale;
-        this.destination = destination;
-    }
-
-    public ModelDestination getDestination() {
-        return destination;
-    }
-
-    public void setDestination(ModelDestination destination) {
-        this.destination = destination;
-    }
-
-    public double getScale() {
-        return scale;
-    }
-
-    public void setScale(double scale) {
-        this.scale = scale;
-    }
-
-    public ModelSource[] getSources() {
-        return sources;
-    }
-
-    public void setSources(ModelSource[] source) {
-        this.sources = source;
-    }
-
-    public void addSource(ModelSource source) {
-        ModelSource[] oldsources = sources;
-        sources = new ModelSource[oldsources.length + 1];
-        for (int i = 0; i < oldsources.length; i++) {
-            sources[i] = oldsources[i];
-        }
-        sources[sources.length - 1] = source;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Connection blocks are used to connect source variable
+ * to a destination variable.
+ * For example Note On velocity can be connected to output gain.
+ * In DLS this is called articulator and in SoundFonts (SF2) a modulator.
+ *
+ * @author Karl Helgason
+ */
+public class ModelConnectionBlock {
+
+    //
+    //   source1 * source2 * scale -> destination
+    //
+    private final static ModelSource[] no_sources = new ModelSource[0];
+    private ModelSource[] sources = no_sources;
+    private double scale = 1;
+    private ModelDestination destination;
+
+    public ModelConnectionBlock() {
+    }
+
+    public ModelConnectionBlock(double scale, ModelDestination destination) {
+        this.scale = scale;
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source,
+            ModelDestination destination) {
+        if (source != null) {
+            this.sources = new ModelSource[1];
+            this.sources[0] = source;
+        }
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source, double scale,
+            ModelDestination destination) {
+        if (source != null) {
+            this.sources = new ModelSource[1];
+            this.sources[0] = source;
+        }
+        this.scale = scale;
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source, ModelSource control,
+            ModelDestination destination) {
+        if (source != null) {
+            if (control == null) {
+                this.sources = new ModelSource[1];
+                this.sources[0] = source;
+            } else {
+                this.sources = new ModelSource[2];
+                this.sources[0] = source;
+                this.sources[1] = control;
+            }
+        }
+        this.destination = destination;
+    }
+
+    public ModelConnectionBlock(ModelSource source, ModelSource control,
+            double scale, ModelDestination destination) {
+        if (source != null) {
+            if (control == null) {
+                this.sources = new ModelSource[1];
+                this.sources[0] = source;
+            } else {
+                this.sources = new ModelSource[2];
+                this.sources[0] = source;
+                this.sources[1] = control;
+            }
+        }
+        this.scale = scale;
+        this.destination = destination;
+    }
+
+    public ModelDestination getDestination() {
+        return destination;
+    }
+
+    public void setDestination(ModelDestination destination) {
+        this.destination = destination;
+    }
+
+    public double getScale() {
+        return scale;
+    }
+
+    public void setScale(double scale) {
+        this.scale = scale;
+    }
+
+    public ModelSource[] getSources() {
+        return sources;
+    }
+
+    public void setSources(ModelSource[] source) {
+        this.sources = source;
+    }
+
+    public void addSource(ModelSource source) {
+        ModelSource[] oldsources = sources;
+        sources = new ModelSource[oldsources.length + 1];
+        for (int i = 0; i < oldsources.length; i++) {
+            sources[i] = oldsources[i];
+        }
+        sources[sources.length - 1] = source;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelDestination.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelDestination.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,117 +1,117 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This class is used to identify destinations in connection blocks,
- * see ModelConnectionBlock.
- *
- * @author Karl Helgason
- */
-public class ModelDestination {
-
-    public static final ModelIdentifier DESTINATION_NONE = null;
-    public static final ModelIdentifier DESTINATION_KEYNUMBER
-            = new ModelIdentifier("noteon", "keynumber");
-    public static final ModelIdentifier DESTINATION_VELOCITY
-            = new ModelIdentifier("noteon", "velocity");
-    public static final ModelIdentifier DESTINATION_PITCH
-            = new ModelIdentifier("osc", "pitch");   // cent
-    public static final ModelIdentifier DESTINATION_GAIN
-            = new ModelIdentifier("mixer", "gain");   // cB
-    public static final ModelIdentifier DESTINATION_PAN
-            = new ModelIdentifier("mixer", "pan");   // 0.1 %
-    public static final ModelIdentifier DESTINATION_REVERB
-            = new ModelIdentifier("mixer", "reverb");   // 0.1 %
-    public static final ModelIdentifier DESTINATION_CHORUS
-            = new ModelIdentifier("mixer", "chorus");   // 0.1 %
-    public static final ModelIdentifier DESTINATION_LFO1_DELAY
-            = new ModelIdentifier("lfo", "delay", 0); // timecent
-    public static final ModelIdentifier DESTINATION_LFO1_FREQ
-            = new ModelIdentifier("lfo", "freq", 0); // cent
-    public static final ModelIdentifier DESTINATION_LFO2_DELAY
-            = new ModelIdentifier("lfo", "delay", 1); // timecent
-    public static final ModelIdentifier DESTINATION_LFO2_FREQ
-            = new ModelIdentifier("lfo", "freq", 1); // cent
-    public static final ModelIdentifier DESTINATION_EG1_DELAY
-            = new ModelIdentifier("eg", "delay", 0); // timecent
-    public static final ModelIdentifier DESTINATION_EG1_ATTACK
-            = new ModelIdentifier("eg", "attack", 0); // timecent
-    public static final ModelIdentifier DESTINATION_EG1_HOLD
-            = new ModelIdentifier("eg", "hold", 0); // timecent
-    public static final ModelIdentifier DESTINATION_EG1_DECAY
-            = new ModelIdentifier("eg", "decay", 0); // timecent
-    public static final ModelIdentifier DESTINATION_EG1_SUSTAIN
-            = new ModelIdentifier("eg", "sustain", 0);
-                                        // 0.1 % (I want this to be value not %)
-    public static final ModelIdentifier DESTINATION_EG1_RELEASE
-            = new ModelIdentifier("eg", "release", 0); // timecent
-    public static final ModelIdentifier DESTINATION_EG1_SHUTDOWN
-            = new ModelIdentifier("eg", "shutdown", 0); // timecent
-    public static final ModelIdentifier DESTINATION_EG2_DELAY
-            = new ModelIdentifier("eg", "delay", 1); // timecent
-    public static final ModelIdentifier DESTINATION_EG2_ATTACK
-            = new ModelIdentifier("eg", "attack", 1); // timecent
-    public static final ModelIdentifier DESTINATION_EG2_HOLD
-            = new ModelIdentifier("eg", "hold", 1); // 0.1 %
-    public static final ModelIdentifier DESTINATION_EG2_DECAY
-            = new ModelIdentifier("eg", "decay", 1); // timecent
-    public static final ModelIdentifier DESTINATION_EG2_SUSTAIN
-            = new ModelIdentifier("eg", "sustain", 1);
-                                        // 0.1 % ( I want this to be value not %)
-    public static final ModelIdentifier DESTINATION_EG2_RELEASE
-            = new ModelIdentifier("eg", "release", 1); // timecent
-    public static final ModelIdentifier DESTINATION_EG2_SHUTDOWN
-            = new ModelIdentifier("eg", "shutdown", 1); // timecent
-    public static final ModelIdentifier DESTINATION_FILTER_FREQ
-            = new ModelIdentifier("filter", "freq", 0); // cent
-    public static final ModelIdentifier DESTINATION_FILTER_Q
-            = new ModelIdentifier("filter", "q", 0); // cB
-    private ModelIdentifier destination = DESTINATION_NONE;
-    private ModelTransform transform = new ModelStandardTransform();
-
-    public ModelDestination() {
-    }
-
-    public ModelDestination(ModelIdentifier id) {
-        destination = id;
-    }
-
-    public ModelIdentifier getIdentifier() {
-        return destination;
-    }
-
-    public void setIdentifier(ModelIdentifier destination) {
-        this.destination = destination;
-    }
-
-    public ModelTransform getTransform() {
-        return transform;
-    }
-
-    public void setTransform(ModelTransform transform) {
-        this.transform = transform;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to identify destinations in connection blocks,
+ * see ModelConnectionBlock.
+ *
+ * @author Karl Helgason
+ */
+public class ModelDestination {
+
+    public static final ModelIdentifier DESTINATION_NONE = null;
+    public static final ModelIdentifier DESTINATION_KEYNUMBER
+            = new ModelIdentifier("noteon", "keynumber");
+    public static final ModelIdentifier DESTINATION_VELOCITY
+            = new ModelIdentifier("noteon", "velocity");
+    public static final ModelIdentifier DESTINATION_PITCH
+            = new ModelIdentifier("osc", "pitch");   // cent
+    public static final ModelIdentifier DESTINATION_GAIN
+            = new ModelIdentifier("mixer", "gain");   // cB
+    public static final ModelIdentifier DESTINATION_PAN
+            = new ModelIdentifier("mixer", "pan");   // 0.1 %
+    public static final ModelIdentifier DESTINATION_REVERB
+            = new ModelIdentifier("mixer", "reverb");   // 0.1 %
+    public static final ModelIdentifier DESTINATION_CHORUS
+            = new ModelIdentifier("mixer", "chorus");   // 0.1 %
+    public static final ModelIdentifier DESTINATION_LFO1_DELAY
+            = new ModelIdentifier("lfo", "delay", 0); // timecent
+    public static final ModelIdentifier DESTINATION_LFO1_FREQ
+            = new ModelIdentifier("lfo", "freq", 0); // cent
+    public static final ModelIdentifier DESTINATION_LFO2_DELAY
+            = new ModelIdentifier("lfo", "delay", 1); // timecent
+    public static final ModelIdentifier DESTINATION_LFO2_FREQ
+            = new ModelIdentifier("lfo", "freq", 1); // cent
+    public static final ModelIdentifier DESTINATION_EG1_DELAY
+            = new ModelIdentifier("eg", "delay", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_ATTACK
+            = new ModelIdentifier("eg", "attack", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_HOLD
+            = new ModelIdentifier("eg", "hold", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_DECAY
+            = new ModelIdentifier("eg", "decay", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_SUSTAIN
+            = new ModelIdentifier("eg", "sustain", 0);
+                                        // 0.1 % (I want this to be value not %)
+    public static final ModelIdentifier DESTINATION_EG1_RELEASE
+            = new ModelIdentifier("eg", "release", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG1_SHUTDOWN
+            = new ModelIdentifier("eg", "shutdown", 0); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_DELAY
+            = new ModelIdentifier("eg", "delay", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_ATTACK
+            = new ModelIdentifier("eg", "attack", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_HOLD
+            = new ModelIdentifier("eg", "hold", 1); // 0.1 %
+    public static final ModelIdentifier DESTINATION_EG2_DECAY
+            = new ModelIdentifier("eg", "decay", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_SUSTAIN
+            = new ModelIdentifier("eg", "sustain", 1);
+                                        // 0.1 % ( I want this to be value not %)
+    public static final ModelIdentifier DESTINATION_EG2_RELEASE
+            = new ModelIdentifier("eg", "release", 1); // timecent
+    public static final ModelIdentifier DESTINATION_EG2_SHUTDOWN
+            = new ModelIdentifier("eg", "shutdown", 1); // timecent
+    public static final ModelIdentifier DESTINATION_FILTER_FREQ
+            = new ModelIdentifier("filter", "freq", 0); // cent
+    public static final ModelIdentifier DESTINATION_FILTER_Q
+            = new ModelIdentifier("filter", "q", 0); // cB
+    private ModelIdentifier destination = DESTINATION_NONE;
+    private ModelTransform transform = new ModelStandardTransform();
+
+    public ModelDestination() {
+    }
+
+    public ModelDestination(ModelIdentifier id) {
+        destination = id;
+    }
+
+    public ModelIdentifier getIdentifier() {
+        return destination;
+    }
+
+    public void setIdentifier(ModelIdentifier destination) {
+        this.destination = destination;
+    }
+
+    public ModelTransform getTransform() {
+        return transform;
+    }
+
+    public void setTransform(ModelTransform transform) {
+        this.transform = transform;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelDirectedPlayer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelDirectedPlayer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,36 +1,36 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- *  ModelDirectedPlayer is the one who is directed by ModelDirector
- *  to play ModelPerformer objects.
- *
- * @author Karl Helgason
- */
-public interface ModelDirectedPlayer {
-
-    public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks);
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ *  ModelDirectedPlayer is the one who is directed by ModelDirector
+ *  to play ModelPerformer objects.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelDirectedPlayer {
+
+    public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks);
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelDirector.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelDirector.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,46 +1,46 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A director chooses what performers should be  played for each note on
- * and note off events.
- *
- * ModelInstrument can implement custom performer who chooses what performers
- * to play for example by sustain pedal is off or on.
- *
- * The default director (ModelStandardDirector) chooses performers
- * by there keyfrom,keyto,velfrom,velto properties.
- *
- * @author Karl Helgason
- */
-public interface ModelDirector {
-
-    public void noteOn(int noteNumber, int velocity);
-
-    public void noteOff(int noteNumber, int velocity);
-
-    public void close();
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A director chooses what performers should be  played for each note on
+ * and note off events.
+ *
+ * ModelInstrument can implement custom performer who chooses what performers
+ * to play for example by sustain pedal is off or on.
+ *
+ * The default director (ModelStandardDirector) chooses performers
+ * by there keyfrom,keyto,velfrom,velto properties.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelDirector {
+
+    public void noteOn(int noteNumber, int velocity);
+
+    public void noteOff(int noteNumber, int velocity);
+
+    public void close();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelIdentifier.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelIdentifier.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,162 +1,162 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This class stores the identity of source and destinations in connection
- * blocks, see ModelConnectionBlock.
- *
- * @author Karl Helgason
- */
-public class ModelIdentifier {
-
-    /*
-     *  Object    Variable
-     *  ------    --------
-     *
-     *  // INPUT parameters
-     *  noteon    keynumber                7 bit midi value
-     *            velocity                 7 bit midi vale
-     *            on                       1 or 0
-     *
-     *  midi      pitch                    14 bit midi value
-     *            channel_pressure         7 bit midi value
-     *            poly_pressure            7 bit midi value
-     *
-     *  midi_cc   0 (midi control #0       7 bit midi value
-     *            1 (midi control #1       7 bit midi value
-     *            ...
-     *            127 (midi control #127   7 bit midi value
-     *
-     *  midi_rpn  0 (midi rpn control #0)  14 bit midi value
-     *            1 (midi rpn control #1)  14 bit midi value
-     *            ....
-     *
-     *  // DAHDSR envelope generator
-     *  eg        (null)
-     *            delay                    timecent
-     *            attack                   timecent
-     *            hold                     timecent
-     *            decay                    timecent
-     *            sustain                  0.1 %
-     *            release                  timecent
-     *
-     *  // Low frequency oscillirator (sine wave)
-     *  lfo       (null)
-     *            delay                    timcent
-     *            freq                     cent
-     *
-     *  // Resonance LowPass Filter 6dB slope
-     *  filter    (null) (output/input)
-     *            freq                     cent
-     *            q                        cB
-     *
-     *  // The oscillator with preloaded wavetable data
-     *  osc       (null)
-     *            pitch                    cent
-     *
-     *  // Output mixer pins
-     *  mixer     gain                     cB
-     *            pan                      0.1 %
-     *            reverb                   0.1 %
-     *            chorus                   0.1 %
-     *
-     */
-    private String object = null;
-    private String variable = null;
-    private int instance = 0;
-
-    public ModelIdentifier(String object) {
-        this.object = object;
-    }
-
-    public ModelIdentifier(String object, int instance) {
-        this.object = object;
-        this.instance = instance;
-    }
-
-    public ModelIdentifier(String object, String variable) {
-        this.object = object;
-        this.variable = variable;
-
-    }
-
-    public ModelIdentifier(String object, String variable, int instance) {
-        this.object = object;
-        this.variable = variable;
-        this.instance = instance;
-
-    }
-
-    public int getInstance() {
-        return instance;
-    }
-
-    public void setInstance(int instance) {
-        this.instance = instance;
-    }
-
-    public String getObject() {
-        return object;
-    }
-
-    public void setObject(String object) {
-        this.object = object;
-    }
-
-    public String getVariable() {
-        return variable;
-    }
-
-    public void setVariable(String variable) {
-        this.variable = variable;
-    }
-
-    public boolean equals(Object obj) {
-        if (!(obj instanceof ModelIdentifier))
-            return false;
-
-        ModelIdentifier mobj = (ModelIdentifier)obj;
-        if ((object == null) != (mobj.object == null))
-            return false;
-        if ((variable == null) != (mobj.variable == null))
-            return false;
-        if (mobj.getInstance() != getInstance())
-            return false;
-        if (!(object == null || object.equals(mobj.object)))
-            return false;
-        if (!(variable == null || variable.equals(mobj.variable)))
-            return false;
-        return true;
-    }
-
-    public String toString() {
-        if (variable == null) {
-            return object + "[" + instance + "]";
-        } else {
-            return object + "[" + instance + "]" + "." + variable;
-        }
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class stores the identity of source and destinations in connection
+ * blocks, see ModelConnectionBlock.
+ *
+ * @author Karl Helgason
+ */
+public class ModelIdentifier {
+
+    /*
+     *  Object    Variable
+     *  ------    --------
+     *
+     *  // INPUT parameters
+     *  noteon    keynumber                7 bit midi value
+     *            velocity                 7 bit midi vale
+     *            on                       1 or 0
+     *
+     *  midi      pitch                    14 bit midi value
+     *            channel_pressure         7 bit midi value
+     *            poly_pressure            7 bit midi value
+     *
+     *  midi_cc   0 (midi control #0       7 bit midi value
+     *            1 (midi control #1       7 bit midi value
+     *            ...
+     *            127 (midi control #127   7 bit midi value
+     *
+     *  midi_rpn  0 (midi rpn control #0)  14 bit midi value
+     *            1 (midi rpn control #1)  14 bit midi value
+     *            ....
+     *
+     *  // DAHDSR envelope generator
+     *  eg        (null)
+     *            delay                    timecent
+     *            attack                   timecent
+     *            hold                     timecent
+     *            decay                    timecent
+     *            sustain                  0.1 %
+     *            release                  timecent
+     *
+     *  // Low frequency oscillirator (sine wave)
+     *  lfo       (null)
+     *            delay                    timcent
+     *            freq                     cent
+     *
+     *  // Resonance LowPass Filter 6dB slope
+     *  filter    (null) (output/input)
+     *            freq                     cent
+     *            q                        cB
+     *
+     *  // The oscillator with preloaded wavetable data
+     *  osc       (null)
+     *            pitch                    cent
+     *
+     *  // Output mixer pins
+     *  mixer     gain                     cB
+     *            pan                      0.1 %
+     *            reverb                   0.1 %
+     *            chorus                   0.1 %
+     *
+     */
+    private String object = null;
+    private String variable = null;
+    private int instance = 0;
+
+    public ModelIdentifier(String object) {
+        this.object = object;
+    }
+
+    public ModelIdentifier(String object, int instance) {
+        this.object = object;
+        this.instance = instance;
+    }
+
+    public ModelIdentifier(String object, String variable) {
+        this.object = object;
+        this.variable = variable;
+
+    }
+
+    public ModelIdentifier(String object, String variable, int instance) {
+        this.object = object;
+        this.variable = variable;
+        this.instance = instance;
+
+    }
+
+    public int getInstance() {
+        return instance;
+    }
+
+    public void setInstance(int instance) {
+        this.instance = instance;
+    }
+
+    public String getObject() {
+        return object;
+    }
+
+    public void setObject(String object) {
+        this.object = object;
+    }
+
+    public String getVariable() {
+        return variable;
+    }
+
+    public void setVariable(String variable) {
+        this.variable = variable;
+    }
+
+    public boolean equals(Object obj) {
+        if (!(obj instanceof ModelIdentifier))
+            return false;
+
+        ModelIdentifier mobj = (ModelIdentifier)obj;
+        if ((object == null) != (mobj.object == null))
+            return false;
+        if ((variable == null) != (mobj.variable == null))
+            return false;
+        if (mobj.getInstance() != getInstance())
+            return false;
+        if (!(object == null || object.equals(mobj.object)))
+            return false;
+        if (!(variable == null || variable.equals(mobj.variable)))
+            return false;
+        return true;
+    }
+
+    public String toString() {
+        if (variable == null) {
+            return object + "[" + instance + "]";
+        } else {
+            return object + "[" + instance + "]" + "." + variable;
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelInstrument.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelInstrument.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,136 +1,136 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.Instrument;
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.Patch;
-import javax.sound.midi.Soundbank;
-import javax.sound.sampled.AudioFormat;
-
-/**
- * The model instrument class.
- *
- * <p>The main methods to override are:<br>
- * getPerformer, getDirector, getChannelMixer.
- *
- * <p>Performers are used to define what voices which will
- * playback when using the instrument.<br>
- *
- * ChannelMixer is used to add channel-wide processing
- * on voices output or to define non-voice oriented instruments.<br>
- *
- * Director is used to change how the synthesizer
- * chooses what performers to play on midi events.
- *
- * @author Karl Helgason
- */
-public abstract class ModelInstrument extends Instrument {
-
-    protected ModelInstrument(Soundbank soundbank, Patch patch, String name,
-            Class<?> dataClass) {
-        super(soundbank, patch, name, dataClass);
-    }
-
-    public ModelDirector getDirector(ModelPerformer[] performers,
-            MidiChannel channel, ModelDirectedPlayer player) {
-        return new ModelStandardDirector(performers, player);
-    }
-
-    public ModelPerformer[] getPerformers() {
-        return new ModelPerformer[0];
-    }
-
-    public ModelChannelMixer getChannelMixer(MidiChannel channel,
-            AudioFormat format) {
-        return null;
-    }
-
-    // Get General MIDI 2 Alias patch for this instrument.
-    public Patch getPatchAlias() {
-        Patch patch = getPatch();
-        int program = patch.getProgram();
-        int bank = patch.getBank();
-        if (bank != 0)
-            return patch;
-        boolean percussion = false;
-        if (getPatch() instanceof ModelPatch)
-            percussion = ((ModelPatch)getPatch()).isPercussion();
-        if (percussion)
-            return new Patch(0x78 << 7, program);
-        else
-            return new Patch(0x79 << 7, program);
-    }
-
-    // Return name of all the keys.
-    // This information is generated from ModelPerformer.getName()
-    // returned from getPerformers().
-    public String[] getKeys() {
-        String[] keys = new String[127];
-        for (ModelPerformer performer : getPerformers()) {
-            for (int k = performer.getKeyFrom(); k <= performer.getKeyTo(); k++) {
-                if (keys[k] == null) {
-                    String name = performer.getName();
-                    if (name == null)
-                        name = "untitled";
-                    keys[k] = name;
-                }
-            }
-        }
-        return keys;
-    }
-
-    // Return what channels this instrument will probably response
-    // on General MIDI synthesizer.
-    public boolean[] getChannels() {
-        boolean percussion = false;
-        if (getPatch() instanceof ModelPatch)
-            percussion = ((ModelPatch)getPatch()).isPercussion();
-
-        // Check if instrument is percussion.
-        if (percussion) {
-            boolean[] ch = new boolean[16];
-            for (int i = 0; i < ch.length; i++)
-                ch[i] = false;
-            ch[9] = true;
-            return ch;
-        }
-
-        // Check if instrument uses General MIDI 2 default banks.
-        int bank = getPatch().getBank();
-        if (bank >> 7 == 0x78 || bank >> 7 == 0x79) {
-            boolean[] ch = new boolean[16];
-            for (int i = 0; i < ch.length; i++)
-                ch[i] = true;
-            return ch;
-        }
-
-        boolean[] ch = new boolean[16];
-        for (int i = 0; i < ch.length; i++)
-            ch[i] = true;
-        ch[9] = false;
-        return ch;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * The model instrument class.
+ *
+ * <p>The main methods to override are:<br>
+ * getPerformer, getDirector, getChannelMixer.
+ *
+ * <p>Performers are used to define what voices which will
+ * playback when using the instrument.<br>
+ *
+ * ChannelMixer is used to add channel-wide processing
+ * on voices output or to define non-voice oriented instruments.<br>
+ *
+ * Director is used to change how the synthesizer
+ * chooses what performers to play on midi events.
+ *
+ * @author Karl Helgason
+ */
+public abstract class ModelInstrument extends Instrument {
+
+    protected ModelInstrument(Soundbank soundbank, Patch patch, String name,
+            Class<?> dataClass) {
+        super(soundbank, patch, name, dataClass);
+    }
+
+    public ModelDirector getDirector(ModelPerformer[] performers,
+            MidiChannel channel, ModelDirectedPlayer player) {
+        return new ModelStandardDirector(performers, player);
+    }
+
+    public ModelPerformer[] getPerformers() {
+        return new ModelPerformer[0];
+    }
+
+    public ModelChannelMixer getChannelMixer(MidiChannel channel,
+            AudioFormat format) {
+        return null;
+    }
+
+    // Get General MIDI 2 Alias patch for this instrument.
+    public Patch getPatchAlias() {
+        Patch patch = getPatch();
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        if (bank != 0)
+            return patch;
+        boolean percussion = false;
+        if (getPatch() instanceof ModelPatch)
+            percussion = ((ModelPatch)getPatch()).isPercussion();
+        if (percussion)
+            return new Patch(0x78 << 7, program);
+        else
+            return new Patch(0x79 << 7, program);
+    }
+
+    // Return name of all the keys.
+    // This information is generated from ModelPerformer.getName()
+    // returned from getPerformers().
+    public String[] getKeys() {
+        String[] keys = new String[127];
+        for (ModelPerformer performer : getPerformers()) {
+            for (int k = performer.getKeyFrom(); k <= performer.getKeyTo(); k++) {
+                if (keys[k] == null) {
+                    String name = performer.getName();
+                    if (name == null)
+                        name = "untitled";
+                    keys[k] = name;
+                }
+            }
+        }
+        return keys;
+    }
+
+    // Return what channels this instrument will probably response
+    // on General MIDI synthesizer.
+    public boolean[] getChannels() {
+        boolean percussion = false;
+        if (getPatch() instanceof ModelPatch)
+            percussion = ((ModelPatch)getPatch()).isPercussion();
+
+        // Check if instrument is percussion.
+        if (percussion) {
+            boolean[] ch = new boolean[16];
+            for (int i = 0; i < ch.length; i++)
+                ch[i] = false;
+            ch[9] = true;
+            return ch;
+        }
+
+        // Check if instrument uses General MIDI 2 default banks.
+        int bank = getPatch().getBank();
+        if (bank >> 7 == 0x78 || bank >> 7 == 0x79) {
+            boolean[] ch = new boolean[16];
+            for (int i = 0; i < ch.length; i++)
+                ch[i] = true;
+            return ch;
+        }
+
+        boolean[] ch = new boolean[16];
+        for (int i = 0; i < ch.length; i++)
+            ch[i] = true;
+        ch[9] = false;
+        return ch;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelInstrumentComparator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelInstrumentComparator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,52 +1,52 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.Comparator;
-import javax.sound.midi.Instrument;
-import javax.sound.midi.Patch;
-
-/**
- * Instrument comparator class.
- * Used to order instrument by program, bank, percussion.
- *
- * @author Karl Helgason
- */
-public class ModelInstrumentComparator implements Comparator<Instrument> {
-
-    public int compare(Instrument arg0, Instrument arg1) {
-        Patch p0 = arg0.getPatch();
-        Patch p1 = arg1.getPatch();
-        int a = p0.getBank() * 128 + p0.getProgram();
-        int b = p1.getBank() * 128 + p1.getProgram();
-        if (p0 instanceof ModelPatch) {
-            a += ((ModelPatch)p0).isPercussion() ? 2097152 : 0;
-        }
-        if (p1 instanceof ModelPatch) {
-            b += ((ModelPatch)p1).isPercussion() ? 2097152 : 0;
-        }
-        return a - b;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Comparator;
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+
+/**
+ * Instrument comparator class.
+ * Used to order instrument by program, bank, percussion.
+ *
+ * @author Karl Helgason
+ */
+public class ModelInstrumentComparator implements Comparator<Instrument> {
+
+    public int compare(Instrument arg0, Instrument arg1) {
+        Patch p0 = arg0.getPatch();
+        Patch p1 = arg1.getPatch();
+        int a = p0.getBank() * 128 + p0.getProgram();
+        int b = p1.getBank() * 128 + p1.getProgram();
+        if (p0 instanceof ModelPatch) {
+            a += ((ModelPatch)p0).isPercussion() ? 2097152 : 0;
+        }
+        if (p1 instanceof ModelPatch) {
+            b += ((ModelPatch)p1).isPercussion() ? 2097152 : 0;
+        }
+        return a - b;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelMappedInstrument.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelMappedInstrument.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,62 +1,62 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.Patch;
-import javax.sound.sampled.AudioFormat;
-
-/**
- * This class is used to map instrument to another patch.
- *
- * @author Karl Helgason
- */
-public class ModelMappedInstrument extends ModelInstrument {
-
-    private ModelInstrument ins;
-
-    public ModelMappedInstrument(ModelInstrument ins, Patch patch) {
-        super(ins.getSoundbank(), patch, ins.getName(), ins.getDataClass());
-        this.ins = ins;
-    }
-
-    public Object getData() {
-        return ins.getData();
-    }
-
-    public ModelPerformer[] getPerformers() {
-        return ins.getPerformers();
-    }
-
-    public ModelDirector getDirector(ModelPerformer[] performers,
-            MidiChannel channel, ModelDirectedPlayer player) {
-        return ins.getDirector(performers, channel, player);
-    }
-
-    public ModelChannelMixer getChannelMixer(MidiChannel channel,
-            AudioFormat format) {
-        return ins.getChannelMixer(channel, format);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * This class is used to map instrument to another patch.
+ *
+ * @author Karl Helgason
+ */
+public class ModelMappedInstrument extends ModelInstrument {
+
+    private ModelInstrument ins;
+
+    public ModelMappedInstrument(ModelInstrument ins, Patch patch) {
+        super(ins.getSoundbank(), patch, ins.getName(), ins.getDataClass());
+        this.ins = ins;
+    }
+
+    public Object getData() {
+        return ins.getData();
+    }
+
+    public ModelPerformer[] getPerformers() {
+        return ins.getPerformers();
+    }
+
+    public ModelDirector getDirector(ModelPerformer[] performers,
+            MidiChannel channel, ModelDirectedPlayer player) {
+        return ins.getDirector(performers, channel, player);
+    }
+
+    public ModelChannelMixer getChannelMixer(MidiChannel channel,
+            AudioFormat format) {
+        return ins.getChannelMixer(channel, format);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelOscillator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelOscillator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,44 +1,44 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This interface is used for oscillators.
- * See example in ModelDefaultOscillator which is a wavetable oscillator.
- *
- * @author Karl Helgason
- */
-public interface ModelOscillator {
-
-    public int getChannels();
-
-    /**
-     * Attenuation is in cB.
-     * @return
-     */
-    public float getAttenuation();
-
-    public ModelOscillatorStream open(float samplerate);
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This interface is used for oscillators.
+ * See example in ModelDefaultOscillator which is a wavetable oscillator.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelOscillator {
+
+    public int getChannels();
+
+    /**
+     * Attenuation is in cB.
+     * @return
+     */
+    public float getAttenuation();
+
+    public ModelOscillatorStream open(float samplerate);
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelOscillatorStream.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelOscillatorStream.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,48 +1,48 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.VoiceStatus;
-
-/**
- * This interface is used for audio streams from ModelOscillator.
- *
- * @author Karl Helgason
- */
-public interface ModelOscillatorStream {
-
-    public void setPitch(float pitch); // Pitch is in cents!
-
-    public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber,
-            int velocity);
-
-    public void noteOff(int velocity);
-
-    public int read(float[][] buffer, int offset, int len) throws IOException;
-
-    public void close() throws IOException;
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * This interface is used for audio streams from ModelOscillator.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelOscillatorStream {
+
+    public void setPitch(float pitch); // Pitch is in cents!
+
+    public void noteOn(MidiChannel channel, VoiceStatus voice, int noteNumber,
+            int velocity);
+
+    public void noteOff(int velocity);
+
+    public int read(float[][] buffer, int offset, int len) throws IOException;
+
+    public void close() throws IOException;
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelPatch.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelPatch.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,52 +1,52 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.Patch;
-
-/**
- * A extended patch object that has isPercussion function.
- * Which is necessary to identify percussion instruments
- * from melodic instruments.
- *
- * @author Karl Helgason
- */
-public class ModelPatch extends Patch {
-
-    private boolean percussion = false;
-
-    public ModelPatch(int bank, int program) {
-        super(bank, program);
-    }
-
-    public ModelPatch(int bank, int program, boolean percussion) {
-        super(bank, program);
-        this.percussion = percussion;
-    }
-
-    public boolean isPercussion() {
-        return percussion;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.Patch;
+
+/**
+ * A extended patch object that has isPercussion function.
+ * Which is necessary to identify percussion instruments
+ * from melodic instruments.
+ *
+ * @author Karl Helgason
+ */
+public class ModelPatch extends Patch {
+
+    private boolean percussion = false;
+
+    public ModelPatch(int bank, int program) {
+        super(bank, program);
+    }
+
+    public ModelPatch(int bank, int program, boolean percussion) {
+        super(bank, program);
+        this.percussion = percussion;
+    }
+
+    public boolean isPercussion() {
+        return percussion;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelPerformer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelPerformer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,143 +1,143 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This class is used to define how to synthesize audio in universal maner
- * for both SF2 and DLS instruments.
- *
- * @author Karl Helgason
- */
-public class ModelPerformer {
-
-    private List<ModelOscillator> oscillators = new ArrayList<ModelOscillator>();
-    private List<ModelConnectionBlock> connectionBlocks
-            = new ArrayList<ModelConnectionBlock>();
-    private int keyFrom = 0;
-    private int keyTo = 127;
-    private int velFrom = 0;
-    private int velTo = 127;
-    private int exclusiveClass = 0;
-    private boolean releaseTrigger = false;
-    private boolean selfNonExclusive = false;
-    private Object userObject = null;
-    private boolean addDefaultConnections = true;
-    private String name = null;
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public List<ModelConnectionBlock> getConnectionBlocks() {
-        return connectionBlocks;
-    }
-
-    public void setConnectionBlocks(List<ModelConnectionBlock> connectionBlocks) {
-        this.connectionBlocks = connectionBlocks;
-    }
-
-    public List<ModelOscillator> getOscillators() {
-        return oscillators;
-    }
-
-    public int getExclusiveClass() {
-        return exclusiveClass;
-    }
-
-    public void setExclusiveClass(int exclusiveClass) {
-        this.exclusiveClass = exclusiveClass;
-    }
-
-    public boolean isSelfNonExclusive() {
-        return selfNonExclusive;
-    }
-
-    public void setSelfNonExclusive(boolean selfNonExclusive) {
-        this.selfNonExclusive = selfNonExclusive;
-    }
-
-    public int getKeyFrom() {
-        return keyFrom;
-    }
-
-    public void setKeyFrom(int keyFrom) {
-        this.keyFrom = keyFrom;
-    }
-
-    public int getKeyTo() {
-        return keyTo;
-    }
-
-    public void setKeyTo(int keyTo) {
-        this.keyTo = keyTo;
-    }
-
-    public int getVelFrom() {
-        return velFrom;
-    }
-
-    public void setVelFrom(int velFrom) {
-        this.velFrom = velFrom;
-    }
-
-    public int getVelTo() {
-        return velTo;
-    }
-
-    public void setVelTo(int velTo) {
-        this.velTo = velTo;
-    }
-
-    public boolean isReleaseTriggered() {
-        return releaseTrigger;
-    }
-
-    public void setReleaseTriggered(boolean value) {
-        this.releaseTrigger = value;
-    }
-
-    public Object getUserObject() {
-        return userObject;
-    }
-
-    public void setUserObject(Object object) {
-        userObject = object;
-    }
-
-    public boolean isDefaultConnectionsEnabled() {
-        return addDefaultConnections;
-    }
-
-    public void setDefaultConnectionsEnabled(boolean addDefaultConnections) {
-        this.addDefaultConnections = addDefaultConnections;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This class is used to define how to synthesize audio in universal maner
+ * for both SF2 and DLS instruments.
+ *
+ * @author Karl Helgason
+ */
+public class ModelPerformer {
+
+    private List<ModelOscillator> oscillators = new ArrayList<ModelOscillator>();
+    private List<ModelConnectionBlock> connectionBlocks
+            = new ArrayList<ModelConnectionBlock>();
+    private int keyFrom = 0;
+    private int keyTo = 127;
+    private int velFrom = 0;
+    private int velTo = 127;
+    private int exclusiveClass = 0;
+    private boolean releaseTrigger = false;
+    private boolean selfNonExclusive = false;
+    private Object userObject = null;
+    private boolean addDefaultConnections = true;
+    private String name = null;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<ModelConnectionBlock> getConnectionBlocks() {
+        return connectionBlocks;
+    }
+
+    public void setConnectionBlocks(List<ModelConnectionBlock> connectionBlocks) {
+        this.connectionBlocks = connectionBlocks;
+    }
+
+    public List<ModelOscillator> getOscillators() {
+        return oscillators;
+    }
+
+    public int getExclusiveClass() {
+        return exclusiveClass;
+    }
+
+    public void setExclusiveClass(int exclusiveClass) {
+        this.exclusiveClass = exclusiveClass;
+    }
+
+    public boolean isSelfNonExclusive() {
+        return selfNonExclusive;
+    }
+
+    public void setSelfNonExclusive(boolean selfNonExclusive) {
+        this.selfNonExclusive = selfNonExclusive;
+    }
+
+    public int getKeyFrom() {
+        return keyFrom;
+    }
+
+    public void setKeyFrom(int keyFrom) {
+        this.keyFrom = keyFrom;
+    }
+
+    public int getKeyTo() {
+        return keyTo;
+    }
+
+    public void setKeyTo(int keyTo) {
+        this.keyTo = keyTo;
+    }
+
+    public int getVelFrom() {
+        return velFrom;
+    }
+
+    public void setVelFrom(int velFrom) {
+        this.velFrom = velFrom;
+    }
+
+    public int getVelTo() {
+        return velTo;
+    }
+
+    public void setVelTo(int velTo) {
+        this.velTo = velTo;
+    }
+
+    public boolean isReleaseTriggered() {
+        return releaseTrigger;
+    }
+
+    public void setReleaseTriggered(boolean value) {
+        this.releaseTrigger = value;
+    }
+
+    public Object getUserObject() {
+        return userObject;
+    }
+
+    public void setUserObject(Object object) {
+        userObject = object;
+    }
+
+    public boolean isDefaultConnectionsEnabled() {
+        return addDefaultConnections;
+    }
+
+    public void setDefaultConnectionsEnabled(boolean addDefaultConnections) {
+        this.addDefaultConnections = addDefaultConnections;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelSource.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelSource.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,109 +1,109 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This class is used to identify sources in connection blocks,
- * see ModelConnectionBlock.
- *
- * @author Karl Helgason
- */
-public class ModelSource {
-
-    public static final ModelIdentifier SOURCE_NONE = null;
-    public static final ModelIdentifier SOURCE_NOTEON_KEYNUMBER =
-            new ModelIdentifier("noteon", "keynumber");     // midi keynumber
-    public static final ModelIdentifier SOURCE_NOTEON_VELOCITY =
-            new ModelIdentifier("noteon", "velocity");      // midi velocity
-    public static final ModelIdentifier SOURCE_EG1 =
-            new ModelIdentifier("eg", null, 0);
-    public static final ModelIdentifier SOURCE_EG2 =
-            new ModelIdentifier("eg", null, 1);
-    public static final ModelIdentifier SOURCE_LFO1 =
-            new ModelIdentifier("lfo", null, 0);
-    public static final ModelIdentifier SOURCE_LFO2 =
-            new ModelIdentifier("lfo", null, 1);
-    public static final ModelIdentifier SOURCE_MIDI_PITCH =
-            new ModelIdentifier("midi", "pitch", 0);            // (0..16383)
-    public static final ModelIdentifier SOURCE_MIDI_CHANNEL_PRESSURE =
-            new ModelIdentifier("midi", "channel_pressure", 0); // (0..127)
-//    public static final ModelIdentifier SOURCE_MIDI_MONO_PRESSURE =
-//            new ModelIdentifier("midi","mono_pressure",0);    // (0..127)
-    public static final ModelIdentifier SOURCE_MIDI_POLY_PRESSURE =
-            new ModelIdentifier("midi", "poly_pressure", 0);    // (0..127)
-    public static final ModelIdentifier SOURCE_MIDI_CC_0 =
-            new ModelIdentifier("midi_cc", "0", 0);             // (0..127)
-    public static final ModelIdentifier SOURCE_MIDI_RPN_0 =
-            new ModelIdentifier("midi_rpn", "0", 0);            // (0..16383)
-    private ModelIdentifier source = SOURCE_NONE;
-    private ModelTransform transform;
-
-    public ModelSource() {
-        this.transform = new ModelStandardTransform();
-    }
-
-    public ModelSource(ModelIdentifier id) {
-        source = id;
-        this.transform = new ModelStandardTransform();
-    }
-
-    public ModelSource(ModelIdentifier id, boolean direction) {
-        source = id;
-        this.transform = new ModelStandardTransform(direction);
-    }
-
-    public ModelSource(ModelIdentifier id, boolean direction, boolean polarity) {
-        source = id;
-        this.transform = new ModelStandardTransform(direction, polarity);
-    }
-
-    public ModelSource(ModelIdentifier id, boolean direction, boolean polarity,
-            int transform) {
-        source = id;
-        this.transform =
-                new ModelStandardTransform(direction, polarity, transform);
-    }
-
-    public ModelSource(ModelIdentifier id, ModelTransform transform) {
-        source = id;
-        this.transform = transform;
-    }
-
-    public ModelIdentifier getIdentifier() {
-        return source;
-    }
-
-    public void setIdentifier(ModelIdentifier source) {
-        this.source = source;
-    }
-
-    public ModelTransform getTransform() {
-        return transform;
-    }
-
-    public void setTransform(ModelTransform transform) {
-        this.transform = transform;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This class is used to identify sources in connection blocks,
+ * see ModelConnectionBlock.
+ *
+ * @author Karl Helgason
+ */
+public class ModelSource {
+
+    public static final ModelIdentifier SOURCE_NONE = null;
+    public static final ModelIdentifier SOURCE_NOTEON_KEYNUMBER =
+            new ModelIdentifier("noteon", "keynumber");     // midi keynumber
+    public static final ModelIdentifier SOURCE_NOTEON_VELOCITY =
+            new ModelIdentifier("noteon", "velocity");      // midi velocity
+    public static final ModelIdentifier SOURCE_EG1 =
+            new ModelIdentifier("eg", null, 0);
+    public static final ModelIdentifier SOURCE_EG2 =
+            new ModelIdentifier("eg", null, 1);
+    public static final ModelIdentifier SOURCE_LFO1 =
+            new ModelIdentifier("lfo", null, 0);
+    public static final ModelIdentifier SOURCE_LFO2 =
+            new ModelIdentifier("lfo", null, 1);
+    public static final ModelIdentifier SOURCE_MIDI_PITCH =
+            new ModelIdentifier("midi", "pitch", 0);            // (0..16383)
+    public static final ModelIdentifier SOURCE_MIDI_CHANNEL_PRESSURE =
+            new ModelIdentifier("midi", "channel_pressure", 0); // (0..127)
+//    public static final ModelIdentifier SOURCE_MIDI_MONO_PRESSURE =
+//            new ModelIdentifier("midi","mono_pressure",0);    // (0..127)
+    public static final ModelIdentifier SOURCE_MIDI_POLY_PRESSURE =
+            new ModelIdentifier("midi", "poly_pressure", 0);    // (0..127)
+    public static final ModelIdentifier SOURCE_MIDI_CC_0 =
+            new ModelIdentifier("midi_cc", "0", 0);             // (0..127)
+    public static final ModelIdentifier SOURCE_MIDI_RPN_0 =
+            new ModelIdentifier("midi_rpn", "0", 0);            // (0..16383)
+    private ModelIdentifier source = SOURCE_NONE;
+    private ModelTransform transform;
+
+    public ModelSource() {
+        this.transform = new ModelStandardTransform();
+    }
+
+    public ModelSource(ModelIdentifier id) {
+        source = id;
+        this.transform = new ModelStandardTransform();
+    }
+
+    public ModelSource(ModelIdentifier id, boolean direction) {
+        source = id;
+        this.transform = new ModelStandardTransform(direction);
+    }
+
+    public ModelSource(ModelIdentifier id, boolean direction, boolean polarity) {
+        source = id;
+        this.transform = new ModelStandardTransform(direction, polarity);
+    }
+
+    public ModelSource(ModelIdentifier id, boolean direction, boolean polarity,
+            int transform) {
+        source = id;
+        this.transform =
+                new ModelStandardTransform(direction, polarity, transform);
+    }
+
+    public ModelSource(ModelIdentifier id, ModelTransform transform) {
+        source = id;
+        this.transform = transform;
+    }
+
+    public ModelIdentifier getIdentifier() {
+        return source;
+    }
+
+    public void setIdentifier(ModelIdentifier source) {
+        this.source = source;
+    }
+
+    public ModelTransform getTransform() {
+        return transform;
+    }
+
+    public void setTransform(ModelTransform transform) {
+        this.transform = transform;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardDirector.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,86 +1,86 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A standard director who chooses performers
- * by there keyfrom,keyto,velfrom,velto properties.
- *
- * @author Karl Helgason
- */
-public class ModelStandardDirector implements ModelDirector {
-
-    ModelPerformer[] performers;
-    ModelDirectedPlayer player;
-    boolean noteOnUsed = false;
-    boolean noteOffUsed = false;
-
-    public ModelStandardDirector(ModelPerformer[] performers,
-            ModelDirectedPlayer player) {
-        this.performers = performers;
-        this.player = player;
-        for (int i = 0; i < performers.length; i++) {
-            ModelPerformer p = performers[i];
-            if (p.isReleaseTriggered()) {
-                noteOffUsed = true;
-            } else {
-                noteOnUsed = true;
-            }
-        }
-    }
-
-    public void close() {
-    }
-
-    public void noteOff(int noteNumber, int velocity) {
-        if (!noteOffUsed)
-            return;
-        for (int i = 0; i < performers.length; i++) {
-            ModelPerformer p = performers[i];
-            if (p.getKeyFrom() <= noteNumber && p.getKeyTo() >= noteNumber) {
-                if (p.getVelFrom() <= velocity && p.getVelTo() >= velocity) {
-                    if (p.isReleaseTriggered()) {
-                        player.play(i, null);
-                    }
-                }
-            }
-        }
-    }
-
-    public void noteOn(int noteNumber, int velocity) {
-        if (!noteOnUsed)
-            return;
-        for (int i = 0; i < performers.length; i++) {
-            ModelPerformer p = performers[i];
-            if (p.getKeyFrom() <= noteNumber && p.getKeyTo() >= noteNumber) {
-                if (p.getVelFrom() <= velocity && p.getVelTo() >= velocity) {
-                    if (!p.isReleaseTriggered()) {
-                        player.play(i, null);
-                    }
-                }
-            }
-        }
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A standard director who chooses performers
+ * by there keyfrom,keyto,velfrom,velto properties.
+ *
+ * @author Karl Helgason
+ */
+public class ModelStandardDirector implements ModelDirector {
+
+    ModelPerformer[] performers;
+    ModelDirectedPlayer player;
+    boolean noteOnUsed = false;
+    boolean noteOffUsed = false;
+
+    public ModelStandardDirector(ModelPerformer[] performers,
+            ModelDirectedPlayer player) {
+        this.performers = performers;
+        this.player = player;
+        for (int i = 0; i < performers.length; i++) {
+            ModelPerformer p = performers[i];
+            if (p.isReleaseTriggered()) {
+                noteOffUsed = true;
+            } else {
+                noteOnUsed = true;
+            }
+        }
+    }
+
+    public void close() {
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+        if (!noteOffUsed)
+            return;
+        for (int i = 0; i < performers.length; i++) {
+            ModelPerformer p = performers[i];
+            if (p.getKeyFrom() <= noteNumber && p.getKeyTo() >= noteNumber) {
+                if (p.getVelFrom() <= velocity && p.getVelTo() >= velocity) {
+                    if (p.isReleaseTriggered()) {
+                        player.play(i, null);
+                    }
+                }
+            }
+        }
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+        if (!noteOnUsed)
+            return;
+        for (int i = 0; i < performers.length; i++) {
+            ModelPerformer p = performers[i];
+            if (p.getKeyFrom() <= noteNumber && p.getKeyTo() >= noteNumber) {
+                if (p.getVelFrom() <= velocity && p.getVelTo() >= velocity) {
+                    if (!p.isReleaseTriggered()) {
+                        player.play(i, null);
+                    }
+                }
+            }
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelStandardTransform.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelStandardTransform.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,139 +1,139 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A standard transformer used in connection blocks.
- * It expects input values to be between 0 and 1.
- *
- * The result of the transform is
- *   between 0 and 1 if polarity = unipolar and
- *   between -1 and 1 if polarity = bipolar.
- *
- * These constraints only applies to Concave, Convex and Switch transforms.
- *
- * @author Karl Helgason
- */
-public class ModelStandardTransform implements ModelTransform {
-
-    public static final boolean DIRECTION_MIN2MAX = false;
-    public static final boolean DIRECTION_MAX2MIN = true;
-    public static final boolean POLARITY_UNIPOLAR = false;
-    public static final boolean POLARITY_BIPOLAR = true;
-    public static final int TRANSFORM_LINEAR = 0;
-    // concave: output = (20*log10(127^2/value^2)) / 96
-    public static final int TRANSFORM_CONCAVE = 1;
-    // convex: same as concave except that start and end point are reversed.
-    public static final int TRANSFORM_CONVEX = 2;
-    // switch: if value > avg(max,min) then max else min
-    public static final int TRANSFORM_SWITCH = 3;
-    public static final int TRANSFORM_ABSOLUTE = 4;
-    private boolean direction = DIRECTION_MIN2MAX;
-    private boolean polarity = POLARITY_UNIPOLAR;
-    private int transform = TRANSFORM_LINEAR;
-
-    public ModelStandardTransform() {
-    }
-
-    public ModelStandardTransform(boolean direction) {
-        this.direction = direction;
-    }
-
-    public ModelStandardTransform(boolean direction, boolean polarity) {
-        this.direction = direction;
-        this.polarity = polarity;
-    }
-
-    public ModelStandardTransform(boolean direction, boolean polarity,
-            int transform) {
-        this.direction = direction;
-        this.polarity = polarity;
-        this.transform = transform;
-    }
-
-    public double transform(double value) {
-        double s;
-        double a;
-        if (direction == DIRECTION_MAX2MIN)
-            value = 1.0 - value;
-        if (polarity == POLARITY_BIPOLAR)
-            value = value * 2.0 - 1.0;
-        switch (transform) {
-            case TRANSFORM_CONCAVE:
-                s = Math.signum(value);
-                a = Math.abs(value);
-                a = -((5.0 / 12.0) / Math.log(10)) * Math.log(1.0 - a);
-                if (a < 0)
-                    a = 0;
-                else if (a > 1)
-                    a = 1;
-                return s * a;
-            case TRANSFORM_CONVEX:
-                s = Math.signum(value);
-                a = Math.abs(value);
-                a = 1.0 + ((5.0 / 12.0) / Math.log(10)) * Math.log(a);
-                if (a < 0)
-                    a = 0;
-                else if (a > 1)
-                    a = 1;
-                return s * a;
-            case TRANSFORM_SWITCH:
-                if (polarity == POLARITY_BIPOLAR)
-                    return (value > 0) ? 1 : -1;
-                else
-                    return (value > 0.5) ? 1 : 0;
-            case TRANSFORM_ABSOLUTE:
-                return Math.abs(value);
-            default:
-                break;
-        }
-
-        return value;
-    }
-
-    public boolean getDirection() {
-        return direction;
-    }
-
-    public void setDirection(boolean direction) {
-        this.direction = direction;
-    }
-
-    public boolean getPolarity() {
-        return polarity;
-    }
-
-    public void setPolarity(boolean polarity) {
-        this.polarity = polarity;
-    }
-
-    public int getTransform() {
-        return transform;
-    }
-
-    public void setTransform(int transform) {
-        this.transform = transform;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A standard transformer used in connection blocks.
+ * It expects input values to be between 0 and 1.
+ *
+ * The result of the transform is
+ *   between 0 and 1 if polarity = unipolar and
+ *   between -1 and 1 if polarity = bipolar.
+ *
+ * These constraints only applies to Concave, Convex and Switch transforms.
+ *
+ * @author Karl Helgason
+ */
+public class ModelStandardTransform implements ModelTransform {
+
+    public static final boolean DIRECTION_MIN2MAX = false;
+    public static final boolean DIRECTION_MAX2MIN = true;
+    public static final boolean POLARITY_UNIPOLAR = false;
+    public static final boolean POLARITY_BIPOLAR = true;
+    public static final int TRANSFORM_LINEAR = 0;
+    // concave: output = (20*log10(127^2/value^2)) / 96
+    public static final int TRANSFORM_CONCAVE = 1;
+    // convex: same as concave except that start and end point are reversed.
+    public static final int TRANSFORM_CONVEX = 2;
+    // switch: if value > avg(max,min) then max else min
+    public static final int TRANSFORM_SWITCH = 3;
+    public static final int TRANSFORM_ABSOLUTE = 4;
+    private boolean direction = DIRECTION_MIN2MAX;
+    private boolean polarity = POLARITY_UNIPOLAR;
+    private int transform = TRANSFORM_LINEAR;
+
+    public ModelStandardTransform() {
+    }
+
+    public ModelStandardTransform(boolean direction) {
+        this.direction = direction;
+    }
+
+    public ModelStandardTransform(boolean direction, boolean polarity) {
+        this.direction = direction;
+        this.polarity = polarity;
+    }
+
+    public ModelStandardTransform(boolean direction, boolean polarity,
+            int transform) {
+        this.direction = direction;
+        this.polarity = polarity;
+        this.transform = transform;
+    }
+
+    public double transform(double value) {
+        double s;
+        double a;
+        if (direction == DIRECTION_MAX2MIN)
+            value = 1.0 - value;
+        if (polarity == POLARITY_BIPOLAR)
+            value = value * 2.0 - 1.0;
+        switch (transform) {
+            case TRANSFORM_CONCAVE:
+                s = Math.signum(value);
+                a = Math.abs(value);
+                a = -((5.0 / 12.0) / Math.log(10)) * Math.log(1.0 - a);
+                if (a < 0)
+                    a = 0;
+                else if (a > 1)
+                    a = 1;
+                return s * a;
+            case TRANSFORM_CONVEX:
+                s = Math.signum(value);
+                a = Math.abs(value);
+                a = 1.0 + ((5.0 / 12.0) / Math.log(10)) * Math.log(a);
+                if (a < 0)
+                    a = 0;
+                else if (a > 1)
+                    a = 1;
+                return s * a;
+            case TRANSFORM_SWITCH:
+                if (polarity == POLARITY_BIPOLAR)
+                    return (value > 0) ? 1 : -1;
+                else
+                    return (value > 0.5) ? 1 : 0;
+            case TRANSFORM_ABSOLUTE:
+                return Math.abs(value);
+            default:
+                break;
+        }
+
+        return value;
+    }
+
+    public boolean getDirection() {
+        return direction;
+    }
+
+    public void setDirection(boolean direction) {
+        this.direction = direction;
+    }
+
+    public boolean getPolarity() {
+        return polarity;
+    }
+
+    public void setPolarity(boolean polarity) {
+        this.polarity = polarity;
+    }
+
+    public int getTransform() {
+        return transform;
+    }
+
+    public void setTransform(int transform) {
+        this.transform = transform;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelTransform.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelTransform.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,35 +1,35 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Model transform interface.
- *
- * @author Karl Helgason
- */
-public interface ModelTransform {
-
-    abstract public double transform(double value);
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Model transform interface.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelTransform {
+
+    abstract public double transform(double value);
+}
--- a/jdk/src/share/classes/com/sun/media/sound/ModelWavetable.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/ModelWavetable.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,49 +1,49 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This is a wavetable oscillator interface.
- *
- * @author Karl Helgason
- */
-public interface ModelWavetable extends ModelOscillator {
-
-    public static final int LOOP_TYPE_OFF = 0;
-    public static final int LOOP_TYPE_FORWARD = 1;
-    public static final int LOOP_TYPE_RELEASE = 2;
-    public static final int LOOP_TYPE_PINGPONG = 4;
-    public static final int LOOP_TYPE_REVERSE = 8;
-
-    public AudioFloatInputStream openStream();
-
-    public float getLoopLength();
-
-    public float getLoopStart();
-
-    public int getLoopType();
-
-    public float getPitchcorrection();
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This is a wavetable oscillator interface.
+ *
+ * @author Karl Helgason
+ */
+public interface ModelWavetable extends ModelOscillator {
+
+    public static final int LOOP_TYPE_OFF = 0;
+    public static final int LOOP_TYPE_FORWARD = 1;
+    public static final int LOOP_TYPE_RELEASE = 2;
+    public static final int LOOP_TYPE_PINGPONG = 4;
+    public static final int LOOP_TYPE_REVERSE = 8;
+
+    public AudioFloatInputStream openStream();
+
+    public float getLoopLength();
+
+    public float getLoopStart();
+
+    public int getLoopType();
+
+    public float getPitchcorrection();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/RIFFInvalidDataException.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFInvalidDataException.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,43 +1,43 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This exception is used when a RIFF file contains illegal or unexpected data.
- *
- * @author Karl Helgason
- */
-public class RIFFInvalidDataException extends InvalidDataException {
-
-    private static final long serialVersionUID = 1L;
-
-    public RIFFInvalidDataException() {
-        super("Invalid Data!");
-    }
-
-    public RIFFInvalidDataException(String s) {
-        super(s);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This exception is used when a RIFF file contains illegal or unexpected data.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFInvalidDataException extends InvalidDataException {
+
+    private static final long serialVersionUID = 1L;
+
+    public RIFFInvalidDataException() {
+        super("Invalid Data!");
+    }
+
+    public RIFFInvalidDataException(String s) {
+        super(s);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/RIFFInvalidFormatException.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFInvalidFormatException.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,44 +1,44 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * This exception is used when a reader is used to read RIFF file of a format it
- * doesn't unterstand or support.
- *
- * @author Karl Helgason
- */
-public class RIFFInvalidFormatException extends InvalidFormatException {
-
-    private static final long serialVersionUID = 1L;
-
-    public RIFFInvalidFormatException() {
-        super("Invalid format!");
-    }
-
-    public RIFFInvalidFormatException(String s) {
-        super(s);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * This exception is used when a reader is used to read RIFF file of a format it
+ * doesn't unterstand or support.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFInvalidFormatException extends InvalidFormatException {
+
+    private static final long serialVersionUID = 1L;
+
+    public RIFFInvalidFormatException() {
+        super("Invalid format!");
+    }
+
+    public RIFFInvalidFormatException(String s) {
+        super(s);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/RIFFReader.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFReader.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,302 +1,302 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Resource Interchange File Format (RIFF) stream decoder.
- *
- * @author Karl Helgason
- */
-public class RIFFReader extends InputStream {
-
-    private RIFFReader root;
-    private long filepointer = 0;
-    private String fourcc;
-    private String riff_type = null;
-    private long ckSize = 0;
-    private InputStream stream;
-    private long avail;
-    private RIFFReader lastiterator = null;
-
-    public RIFFReader(InputStream stream) throws IOException {
-
-        if (stream instanceof RIFFReader)
-            root = ((RIFFReader)stream).root;
-        else
-            root = this;
-
-        this.stream = stream;
-        avail = stream.available();
-        ckSize = stream.available();
-
-        // Check for RIFF null paddings,
-        int b;
-        while (true) {
-            b = read();
-            if (b == -1) {
-                fourcc = ""; // don't put null value into fourcc,
-                // because it is expected to
-                // always contain a string value
-                riff_type = null;
-                avail = 0;
-                return;
-            }
-            if (b != 0)
-                break;
-        }
-
-        byte[] fourcc = new byte[4];
-        fourcc[0] = (byte) b;
-        read(fourcc, 1, 3);
-        this.fourcc = new String(fourcc, "ascii");
-        ckSize = readUnsignedInt();
-
-        avail = this.ckSize;
-
-        if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
-            byte[] format = new byte[4];
-            read(format);
-            this.riff_type = new String(format, "ascii");
-        }
-    }
-
-    public long getFilePointer() throws IOException {
-        return root.filepointer;
-    }
-
-    public boolean hasNextChunk() throws IOException {
-        if (lastiterator != null)
-            lastiterator.finish();
-        return avail != 0;
-    }
-
-    public RIFFReader nextChunk() throws IOException {
-        if (lastiterator != null)
-            lastiterator.finish();
-        if (avail == 0)
-            return null;
-        lastiterator = new RIFFReader(this);
-        return lastiterator;
-    }
-
-    public String getFormat() {
-        return fourcc;
-    }
-
-    public String getType() {
-        return riff_type;
-    }
-
-    public long getSize() {
-        return ckSize;
-    }
-
-    public int read() throws IOException {
-        if (avail == 0)
-            return -1;
-        int b = stream.read();
-        if (b == -1)
-            return -1;
-        avail--;
-        filepointer++;
-        return b;
-    }
-
-    public int read(byte[] b, int offset, int len) throws IOException {
-        if (avail == 0)
-            return -1;
-        if (len > avail) {
-            int rlen = stream.read(b, offset, (int)avail);
-            if (rlen != -1)
-                filepointer += rlen;
-            avail = 0;
-            return rlen;
-        } else {
-            avail -= len;
-            int ret = stream.read(b, offset, len);
-            if (ret == -1)
-                return -1;
-            filepointer += ret;
-            return ret;
-        }
-    }
-
-    public long skip(long n) throws IOException {
-        if (avail == 0)
-            return -1;
-        if (n > avail) {
-            long len = stream.skip(avail);
-            if (len != -1)
-                filepointer += len;
-            avail = 0;
-            return len;
-        } else {
-            avail -= n;
-            long ret = stream.skip(n);
-            if (ret == -1)
-                return -1;
-            filepointer += ret;
-            return ret;
-        }
-    }
-
-    public int available() {
-        return (int)avail;
-    }
-
-    public void finish() throws IOException {
-        if (avail != 0) {
-            long ret = stream.skip(avail);
-            if (ret != -1)
-                filepointer += ret;
-            avail = 0;
-        }
-    }
-
-    // Read ASCII chars from stream
-    public String readString(int len) throws IOException {
-        byte[] buff = new byte[len];
-        read(buff);
-        for (int i = 0; i < buff.length; i++) {
-            if (buff[i] == 0) {
-                return new String(buff, 0, i, "ascii");
-            }
-        }
-        return new String(buff, "ascii");
-    }
-
-    // Read 8 bit signed integer from stream
-    public byte readByte() throws IOException {
-        int ch = read();
-        if (ch < 0)
-            throw new EOFException();
-        return (byte) ch;
-    }
-
-    // Read 16 bit signed integer from stream
-    public short readShort() throws IOException {
-        int ch1 = read();
-        int ch2 = read();
-        if (ch1 < 0)
-            throw new EOFException();
-        if (ch2 < 0)
-            throw new EOFException();
-        return (short)(ch1 | (ch2 << 8));
-    }
-
-    // Read 32 bit signed integer from stream
-    public int readInt() throws IOException {
-        int ch1 = read();
-        int ch2 = read();
-        int ch3 = read();
-        int ch4 = read();
-        if (ch1 < 0)
-            throw new EOFException();
-        if (ch2 < 0)
-            throw new EOFException();
-        if (ch3 < 0)
-            throw new EOFException();
-        if (ch4 < 0)
-            throw new EOFException();
-        return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
-    }
-
-    // Read 64 bit signed integer from stream
-    public long readLong() throws IOException {
-        long ch1 = read();
-        long ch2 = read();
-        long ch3 = read();
-        long ch4 = read();
-        long ch5 = read();
-        long ch6 = read();
-        long ch7 = read();
-        long ch8 = read();
-        if (ch1 < 0)
-            throw new EOFException();
-        if (ch2 < 0)
-            throw new EOFException();
-        if (ch3 < 0)
-            throw new EOFException();
-        if (ch4 < 0)
-            throw new EOFException();
-        if (ch5 < 0)
-            throw new EOFException();
-        if (ch6 < 0)
-            throw new EOFException();
-        if (ch7 < 0)
-            throw new EOFException();
-        if (ch8 < 0)
-            throw new EOFException();
-        return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24)
-                | (ch5 << 32) | (ch6 << 40) | (ch7 << 48) | (ch8 << 56);
-    }
-
-    // Read 8 bit unsigned integer from stream
-    public int readUnsignedByte() throws IOException {
-        int ch = read();
-        if (ch < 0)
-            throw new EOFException();
-        return ch;
-    }
-
-    // Read 16 bit unsigned integer from stream
-    public int readUnsignedShort() throws IOException {
-        int ch1 = read();
-        int ch2 = read();
-        if (ch1 < 0)
-            throw new EOFException();
-        if (ch2 < 0)
-            throw new EOFException();
-        return ch1 | (ch2 << 8);
-    }
-
-    // Read 32 bit unsigned integer from stream
-    public long readUnsignedInt() throws IOException {
-        long ch1 = read();
-        long ch2 = read();
-        long ch3 = read();
-        long ch4 = read();
-        if (ch1 < 0)
-            throw new EOFException();
-        if (ch2 < 0)
-            throw new EOFException();
-        if (ch3 < 0)
-            throw new EOFException();
-        if (ch4 < 0)
-            throw new EOFException();
-        return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
-    }
-
-    public void close() throws IOException {
-        finish();
-        if (this == root)
-            stream.close();
-        stream = null;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Resource Interchange File Format (RIFF) stream decoder.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFReader extends InputStream {
+
+    private RIFFReader root;
+    private long filepointer = 0;
+    private String fourcc;
+    private String riff_type = null;
+    private long ckSize = 0;
+    private InputStream stream;
+    private long avail;
+    private RIFFReader lastiterator = null;
+
+    public RIFFReader(InputStream stream) throws IOException {
+
+        if (stream instanceof RIFFReader)
+            root = ((RIFFReader)stream).root;
+        else
+            root = this;
+
+        this.stream = stream;
+        avail = stream.available();
+        ckSize = stream.available();
+
+        // Check for RIFF null paddings,
+        int b;
+        while (true) {
+            b = read();
+            if (b == -1) {
+                fourcc = ""; // don't put null value into fourcc,
+                // because it is expected to
+                // always contain a string value
+                riff_type = null;
+                avail = 0;
+                return;
+            }
+            if (b != 0)
+                break;
+        }
+
+        byte[] fourcc = new byte[4];
+        fourcc[0] = (byte) b;
+        read(fourcc, 1, 3);
+        this.fourcc = new String(fourcc, "ascii");
+        ckSize = readUnsignedInt();
+
+        avail = this.ckSize;
+
+        if (getFormat().equals("RIFF") || getFormat().equals("LIST")) {
+            byte[] format = new byte[4];
+            read(format);
+            this.riff_type = new String(format, "ascii");
+        }
+    }
+
+    public long getFilePointer() throws IOException {
+        return root.filepointer;
+    }
+
+    public boolean hasNextChunk() throws IOException {
+        if (lastiterator != null)
+            lastiterator.finish();
+        return avail != 0;
+    }
+
+    public RIFFReader nextChunk() throws IOException {
+        if (lastiterator != null)
+            lastiterator.finish();
+        if (avail == 0)
+            return null;
+        lastiterator = new RIFFReader(this);
+        return lastiterator;
+    }
+
+    public String getFormat() {
+        return fourcc;
+    }
+
+    public String getType() {
+        return riff_type;
+    }
+
+    public long getSize() {
+        return ckSize;
+    }
+
+    public int read() throws IOException {
+        if (avail == 0)
+            return -1;
+        int b = stream.read();
+        if (b == -1)
+            return -1;
+        avail--;
+        filepointer++;
+        return b;
+    }
+
+    public int read(byte[] b, int offset, int len) throws IOException {
+        if (avail == 0)
+            return -1;
+        if (len > avail) {
+            int rlen = stream.read(b, offset, (int)avail);
+            if (rlen != -1)
+                filepointer += rlen;
+            avail = 0;
+            return rlen;
+        } else {
+            avail -= len;
+            int ret = stream.read(b, offset, len);
+            if (ret == -1)
+                return -1;
+            filepointer += ret;
+            return ret;
+        }
+    }
+
+    public long skip(long n) throws IOException {
+        if (avail == 0)
+            return -1;
+        if (n > avail) {
+            long len = stream.skip(avail);
+            if (len != -1)
+                filepointer += len;
+            avail = 0;
+            return len;
+        } else {
+            avail -= n;
+            long ret = stream.skip(n);
+            if (ret == -1)
+                return -1;
+            filepointer += ret;
+            return ret;
+        }
+    }
+
+    public int available() {
+        return (int)avail;
+    }
+
+    public void finish() throws IOException {
+        if (avail != 0) {
+            long ret = stream.skip(avail);
+            if (ret != -1)
+                filepointer += ret;
+            avail = 0;
+        }
+    }
+
+    // Read ASCII chars from stream
+    public String readString(int len) throws IOException {
+        byte[] buff = new byte[len];
+        read(buff);
+        for (int i = 0; i < buff.length; i++) {
+            if (buff[i] == 0) {
+                return new String(buff, 0, i, "ascii");
+            }
+        }
+        return new String(buff, "ascii");
+    }
+
+    // Read 8 bit signed integer from stream
+    public byte readByte() throws IOException {
+        int ch = read();
+        if (ch < 0)
+            throw new EOFException();
+        return (byte) ch;
+    }
+
+    // Read 16 bit signed integer from stream
+    public short readShort() throws IOException {
+        int ch1 = read();
+        int ch2 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        return (short)(ch1 | (ch2 << 8));
+    }
+
+    // Read 32 bit signed integer from stream
+    public int readInt() throws IOException {
+        int ch1 = read();
+        int ch2 = read();
+        int ch3 = read();
+        int ch4 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        if (ch3 < 0)
+            throw new EOFException();
+        if (ch4 < 0)
+            throw new EOFException();
+        return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
+    }
+
+    // Read 64 bit signed integer from stream
+    public long readLong() throws IOException {
+        long ch1 = read();
+        long ch2 = read();
+        long ch3 = read();
+        long ch4 = read();
+        long ch5 = read();
+        long ch6 = read();
+        long ch7 = read();
+        long ch8 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        if (ch3 < 0)
+            throw new EOFException();
+        if (ch4 < 0)
+            throw new EOFException();
+        if (ch5 < 0)
+            throw new EOFException();
+        if (ch6 < 0)
+            throw new EOFException();
+        if (ch7 < 0)
+            throw new EOFException();
+        if (ch8 < 0)
+            throw new EOFException();
+        return ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24)
+                | (ch5 << 32) | (ch6 << 40) | (ch7 << 48) | (ch8 << 56);
+    }
+
+    // Read 8 bit unsigned integer from stream
+    public int readUnsignedByte() throws IOException {
+        int ch = read();
+        if (ch < 0)
+            throw new EOFException();
+        return ch;
+    }
+
+    // Read 16 bit unsigned integer from stream
+    public int readUnsignedShort() throws IOException {
+        int ch1 = read();
+        int ch2 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        return ch1 | (ch2 << 8);
+    }
+
+    // Read 32 bit unsigned integer from stream
+    public long readUnsignedInt() throws IOException {
+        long ch1 = read();
+        long ch2 = read();
+        long ch3 = read();
+        long ch4 = read();
+        if (ch1 < 0)
+            throw new EOFException();
+        if (ch2 < 0)
+            throw new EOFException();
+        if (ch3 < 0)
+            throw new EOFException();
+        if (ch4 < 0)
+            throw new EOFException();
+        return ch1 + (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
+    }
+
+    public void close() throws IOException {
+        finish();
+        if (this == root)
+            stream.close();
+        stream = null;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/RIFFWriter.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/RIFFWriter.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,365 +1,365 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.RandomAccessFile;
-
-/**
- * Resource Interchange File Format (RIFF) stream encoder.
- *
- * @author Karl Helgason
- */
-public class RIFFWriter extends OutputStream {
-
-    private interface RandomAccessWriter {
-
-        public void seek(long chunksizepointer) throws IOException;
-
-        public long getPointer() throws IOException;
-
-        public void close() throws IOException;
-
-        public void write(int b) throws IOException;
-
-        public void write(byte[] b, int off, int len) throws IOException;
-
-        public void write(byte[] bytes) throws IOException;
-
-        public long length() throws IOException;
-
-        public void setLength(long i) throws IOException;
-    }
-
-    private static class RandomAccessFileWriter implements RandomAccessWriter {
-
-        RandomAccessFile raf;
-
-        public RandomAccessFileWriter(File file) throws FileNotFoundException {
-            this.raf = new RandomAccessFile(file, "rw");
-        }
-
-        public RandomAccessFileWriter(String name) throws FileNotFoundException {
-            this.raf = new RandomAccessFile(name, "rw");
-        }
-
-        public void seek(long chunksizepointer) throws IOException {
-            raf.seek(chunksizepointer);
-        }
-
-        public long getPointer() throws IOException {
-            return raf.getFilePointer();
-        }
-
-        public void close() throws IOException {
-            raf.close();
-        }
-
-        public void write(int b) throws IOException {
-            raf.write(b);
-        }
-
-        public void write(byte[] b, int off, int len) throws IOException {
-            raf.write(b, off, len);
-        }
-
-        public void write(byte[] bytes) throws IOException {
-            raf.write(bytes);
-        }
-
-        public long length() throws IOException {
-            return raf.length();
-        }
-
-        public void setLength(long i) throws IOException {
-            raf.setLength(i);
-        }
-    }
-
-    private static class RandomAccessByteWriter implements RandomAccessWriter {
-
-        byte[] buff = new byte[32];
-        int length = 0;
-        int pos = 0;
-        byte[] s;
-        OutputStream stream;
-
-        public RandomAccessByteWriter(OutputStream stream) {
-            this.stream = stream;
-        }
-
-        public void seek(long chunksizepointer) throws IOException {
-            pos = (int) chunksizepointer;
-        }
-
-        public long getPointer() throws IOException {
-            return pos;
-        }
-
-        public void close() throws IOException {
-            stream.write(buff, 0, length);
-            stream.close();
-        }
-
-        public void write(int b) throws IOException {
-            if (s == null)
-                s = new byte[1];
-            s[0] = (byte)b;
-            write(s, 0, 1);
-        }
-
-        public void write(byte[] b, int off, int len) throws IOException {
-            int newsize = pos + len;
-            if (newsize > length)
-                setLength(newsize);
-            int end = off + len;
-            for (int i = off; i < end; i++) {
-                buff[pos++] = b[i];
-            }
-        }
-
-        public void write(byte[] bytes) throws IOException {
-            write(bytes, 0, bytes.length);
-        }
-
-        public long length() throws IOException {
-            return length;
-        }
-
-        public void setLength(long i) throws IOException {
-            length = (int) i;
-            if (length > buff.length) {
-                int newlen = Math.max(buff.length << 1, length);
-                byte[] newbuff = new byte[newlen];
-                System.arraycopy(buff, 0, newbuff, 0, buff.length);
-                buff = newbuff;
-            }
-        }
-    }
-    private int chunktype = 0; // 0=RIFF, 1=LIST; 2=CHUNK
-    private RandomAccessWriter raf;
-    private long chunksizepointer;
-    private long startpointer;
-    private RIFFWriter childchunk = null;
-    private boolean open = true;
-    private boolean writeoverride = false;
-
-    public RIFFWriter(String name, String format) throws IOException {
-        this(new RandomAccessFileWriter(name), format, 0);
-    }
-
-    public RIFFWriter(File file, String format) throws IOException {
-        this(new RandomAccessFileWriter(file), format, 0);
-    }
-
-    public RIFFWriter(OutputStream stream, String format) throws IOException {
-        this(new RandomAccessByteWriter(stream), format, 0);
-    }
-
-    private RIFFWriter(RandomAccessWriter raf, String format, int chunktype)
-            throws IOException {
-        if (chunktype == 0)
-            if (raf.length() != 0)
-                raf.setLength(0);
-        this.raf = raf;
-        if (raf.getPointer() % 2 != 0)
-            raf.write(0);
-
-        if (chunktype == 0)
-            raf.write("RIFF".getBytes("ascii"));
-        else if (chunktype == 1)
-            raf.write("LIST".getBytes("ascii"));
-        else
-            raf.write((format + "    ").substring(0, 4).getBytes("ascii"));
-
-        chunksizepointer = raf.getPointer();
-        this.chunktype = 2;
-        writeUnsignedInt(0);
-        this.chunktype = chunktype;
-        startpointer = raf.getPointer();
-        if (chunktype != 2)
-            raf.write((format + "    ").substring(0, 4).getBytes("ascii"));
-
-    }
-
-    public void seek(long pos) throws IOException {
-        raf.seek(pos);
-    }
-
-    public long getFilePointer() throws IOException {
-        return raf.getPointer();
-    }
-
-    public void setWriteOverride(boolean writeoverride) {
-        this.writeoverride = writeoverride;
-    }
-
-    public boolean getWriteOverride() {
-        return writeoverride;
-    }
-
-    public void close() throws IOException {
-        if (!open)
-            return;
-        if (childchunk != null) {
-            childchunk.close();
-            childchunk = null;
-        }
-
-        int bakchunktype = chunktype;
-        long fpointer = raf.getPointer();
-        raf.seek(chunksizepointer);
-        chunktype = 2;
-        writeUnsignedInt(fpointer - startpointer);
-
-        if (bakchunktype == 0)
-            raf.close();
-        else
-            raf.seek(fpointer);
-        open = false;
-        raf = null;
-    }
-
-    public void write(int b) throws IOException {
-        if (!writeoverride) {
-            if (chunktype != 2) {
-                throw new IllegalArgumentException(
-                        "Only chunks can write bytes!");
-            }
-            if (childchunk != null) {
-                childchunk.close();
-                childchunk = null;
-            }
-        }
-        raf.write(b);
-    }
-
-    public void write(byte b[], int off, int len) throws IOException {
-        if (!writeoverride) {
-            if (chunktype != 2) {
-                throw new IllegalArgumentException(
-                        "Only chunks can write bytes!");
-            }
-            if (childchunk != null) {
-                childchunk.close();
-                childchunk = null;
-            }
-        }
-        raf.write(b, off, len);
-    }
-
-    public RIFFWriter writeList(String format) throws IOException {
-        if (chunktype == 2) {
-            throw new IllegalArgumentException(
-                    "Only LIST and RIFF can write lists!");
-        }
-        if (childchunk != null) {
-            childchunk.close();
-            childchunk = null;
-        }
-        childchunk = new RIFFWriter(this.raf, format, 1);
-        return childchunk;
-    }
-
-    public RIFFWriter writeChunk(String format) throws IOException {
-        if (chunktype == 2) {
-            throw new IllegalArgumentException(
-                    "Only LIST and RIFF can write chunks!");
-        }
-        if (childchunk != null) {
-            childchunk.close();
-            childchunk = null;
-        }
-        childchunk = new RIFFWriter(this.raf, format, 2);
-        return childchunk;
-    }
-
-    // Write ASCII chars to stream
-    public void writeString(String string) throws IOException {
-        byte[] buff = string.getBytes();
-        write(buff);
-    }
-
-    // Write ASCII chars to stream
-    public void writeString(String string, int len) throws IOException {
-        byte[] buff = string.getBytes();
-        if (buff.length > len)
-            write(buff, 0, len);
-        else {
-            write(buff);
-            for (int i = buff.length; i < len; i++)
-                write(0);
-        }
-    }
-
-    // Write 8 bit signed integer to stream
-    public void writeByte(int b) throws IOException {
-        write(b);
-    }
-
-    // Write 16 bit signed integer to stream
-    public void writeShort(short b) throws IOException {
-        write((b >>> 0) & 0xFF);
-        write((b >>> 8) & 0xFF);
-    }
-
-    // Write 32 bit signed integer to stream
-    public void writeInt(int b) throws IOException {
-        write((b >>> 0) & 0xFF);
-        write((b >>> 8) & 0xFF);
-        write((b >>> 16) & 0xFF);
-        write((b >>> 24) & 0xFF);
-    }
-
-    // Write 64 bit signed integer to stream
-    public void writeLong(long b) throws IOException {
-        write((int) (b >>> 0) & 0xFF);
-        write((int) (b >>> 8) & 0xFF);
-        write((int) (b >>> 16) & 0xFF);
-        write((int) (b >>> 24) & 0xFF);
-        write((int) (b >>> 32) & 0xFF);
-        write((int) (b >>> 40) & 0xFF);
-        write((int) (b >>> 48) & 0xFF);
-        write((int) (b >>> 56) & 0xFF);
-    }
-
-    // Write 8 bit unsigned integer to stream
-    public void writeUnsignedByte(int b) throws IOException {
-        writeByte((byte) b);
-    }
-
-    // Write 16 bit unsigned integer to stream
-    public void writeUnsignedShort(int b) throws IOException {
-        writeShort((short) b);
-    }
-
-    // Write 32 bit unsigned integer to stream
-    public void writeUnsignedInt(long b) throws IOException {
-        writeInt((int) b);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+
+/**
+ * Resource Interchange File Format (RIFF) stream encoder.
+ *
+ * @author Karl Helgason
+ */
+public class RIFFWriter extends OutputStream {
+
+    private interface RandomAccessWriter {
+
+        public void seek(long chunksizepointer) throws IOException;
+
+        public long getPointer() throws IOException;
+
+        public void close() throws IOException;
+
+        public void write(int b) throws IOException;
+
+        public void write(byte[] b, int off, int len) throws IOException;
+
+        public void write(byte[] bytes) throws IOException;
+
+        public long length() throws IOException;
+
+        public void setLength(long i) throws IOException;
+    }
+
+    private static class RandomAccessFileWriter implements RandomAccessWriter {
+
+        RandomAccessFile raf;
+
+        public RandomAccessFileWriter(File file) throws FileNotFoundException {
+            this.raf = new RandomAccessFile(file, "rw");
+        }
+
+        public RandomAccessFileWriter(String name) throws FileNotFoundException {
+            this.raf = new RandomAccessFile(name, "rw");
+        }
+
+        public void seek(long chunksizepointer) throws IOException {
+            raf.seek(chunksizepointer);
+        }
+
+        public long getPointer() throws IOException {
+            return raf.getFilePointer();
+        }
+
+        public void close() throws IOException {
+            raf.close();
+        }
+
+        public void write(int b) throws IOException {
+            raf.write(b);
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            raf.write(b, off, len);
+        }
+
+        public void write(byte[] bytes) throws IOException {
+            raf.write(bytes);
+        }
+
+        public long length() throws IOException {
+            return raf.length();
+        }
+
+        public void setLength(long i) throws IOException {
+            raf.setLength(i);
+        }
+    }
+
+    private static class RandomAccessByteWriter implements RandomAccessWriter {
+
+        byte[] buff = new byte[32];
+        int length = 0;
+        int pos = 0;
+        byte[] s;
+        OutputStream stream;
+
+        public RandomAccessByteWriter(OutputStream stream) {
+            this.stream = stream;
+        }
+
+        public void seek(long chunksizepointer) throws IOException {
+            pos = (int) chunksizepointer;
+        }
+
+        public long getPointer() throws IOException {
+            return pos;
+        }
+
+        public void close() throws IOException {
+            stream.write(buff, 0, length);
+            stream.close();
+        }
+
+        public void write(int b) throws IOException {
+            if (s == null)
+                s = new byte[1];
+            s[0] = (byte)b;
+            write(s, 0, 1);
+        }
+
+        public void write(byte[] b, int off, int len) throws IOException {
+            int newsize = pos + len;
+            if (newsize > length)
+                setLength(newsize);
+            int end = off + len;
+            for (int i = off; i < end; i++) {
+                buff[pos++] = b[i];
+            }
+        }
+
+        public void write(byte[] bytes) throws IOException {
+            write(bytes, 0, bytes.length);
+        }
+
+        public long length() throws IOException {
+            return length;
+        }
+
+        public void setLength(long i) throws IOException {
+            length = (int) i;
+            if (length > buff.length) {
+                int newlen = Math.max(buff.length << 1, length);
+                byte[] newbuff = new byte[newlen];
+                System.arraycopy(buff, 0, newbuff, 0, buff.length);
+                buff = newbuff;
+            }
+        }
+    }
+    private int chunktype = 0; // 0=RIFF, 1=LIST; 2=CHUNK
+    private RandomAccessWriter raf;
+    private long chunksizepointer;
+    private long startpointer;
+    private RIFFWriter childchunk = null;
+    private boolean open = true;
+    private boolean writeoverride = false;
+
+    public RIFFWriter(String name, String format) throws IOException {
+        this(new RandomAccessFileWriter(name), format, 0);
+    }
+
+    public RIFFWriter(File file, String format) throws IOException {
+        this(new RandomAccessFileWriter(file), format, 0);
+    }
+
+    public RIFFWriter(OutputStream stream, String format) throws IOException {
+        this(new RandomAccessByteWriter(stream), format, 0);
+    }
+
+    private RIFFWriter(RandomAccessWriter raf, String format, int chunktype)
+            throws IOException {
+        if (chunktype == 0)
+            if (raf.length() != 0)
+                raf.setLength(0);
+        this.raf = raf;
+        if (raf.getPointer() % 2 != 0)
+            raf.write(0);
+
+        if (chunktype == 0)
+            raf.write("RIFF".getBytes("ascii"));
+        else if (chunktype == 1)
+            raf.write("LIST".getBytes("ascii"));
+        else
+            raf.write((format + "    ").substring(0, 4).getBytes("ascii"));
+
+        chunksizepointer = raf.getPointer();
+        this.chunktype = 2;
+        writeUnsignedInt(0);
+        this.chunktype = chunktype;
+        startpointer = raf.getPointer();
+        if (chunktype != 2)
+            raf.write((format + "    ").substring(0, 4).getBytes("ascii"));
+
+    }
+
+    public void seek(long pos) throws IOException {
+        raf.seek(pos);
+    }
+
+    public long getFilePointer() throws IOException {
+        return raf.getPointer();
+    }
+
+    public void setWriteOverride(boolean writeoverride) {
+        this.writeoverride = writeoverride;
+    }
+
+    public boolean getWriteOverride() {
+        return writeoverride;
+    }
+
+    public void close() throws IOException {
+        if (!open)
+            return;
+        if (childchunk != null) {
+            childchunk.close();
+            childchunk = null;
+        }
+
+        int bakchunktype = chunktype;
+        long fpointer = raf.getPointer();
+        raf.seek(chunksizepointer);
+        chunktype = 2;
+        writeUnsignedInt(fpointer - startpointer);
+
+        if (bakchunktype == 0)
+            raf.close();
+        else
+            raf.seek(fpointer);
+        open = false;
+        raf = null;
+    }
+
+    public void write(int b) throws IOException {
+        if (!writeoverride) {
+            if (chunktype != 2) {
+                throw new IllegalArgumentException(
+                        "Only chunks can write bytes!");
+            }
+            if (childchunk != null) {
+                childchunk.close();
+                childchunk = null;
+            }
+        }
+        raf.write(b);
+    }
+
+    public void write(byte b[], int off, int len) throws IOException {
+        if (!writeoverride) {
+            if (chunktype != 2) {
+                throw new IllegalArgumentException(
+                        "Only chunks can write bytes!");
+            }
+            if (childchunk != null) {
+                childchunk.close();
+                childchunk = null;
+            }
+        }
+        raf.write(b, off, len);
+    }
+
+    public RIFFWriter writeList(String format) throws IOException {
+        if (chunktype == 2) {
+            throw new IllegalArgumentException(
+                    "Only LIST and RIFF can write lists!");
+        }
+        if (childchunk != null) {
+            childchunk.close();
+            childchunk = null;
+        }
+        childchunk = new RIFFWriter(this.raf, format, 1);
+        return childchunk;
+    }
+
+    public RIFFWriter writeChunk(String format) throws IOException {
+        if (chunktype == 2) {
+            throw new IllegalArgumentException(
+                    "Only LIST and RIFF can write chunks!");
+        }
+        if (childchunk != null) {
+            childchunk.close();
+            childchunk = null;
+        }
+        childchunk = new RIFFWriter(this.raf, format, 2);
+        return childchunk;
+    }
+
+    // Write ASCII chars to stream
+    public void writeString(String string) throws IOException {
+        byte[] buff = string.getBytes();
+        write(buff);
+    }
+
+    // Write ASCII chars to stream
+    public void writeString(String string, int len) throws IOException {
+        byte[] buff = string.getBytes();
+        if (buff.length > len)
+            write(buff, 0, len);
+        else {
+            write(buff);
+            for (int i = buff.length; i < len; i++)
+                write(0);
+        }
+    }
+
+    // Write 8 bit signed integer to stream
+    public void writeByte(int b) throws IOException {
+        write(b);
+    }
+
+    // Write 16 bit signed integer to stream
+    public void writeShort(short b) throws IOException {
+        write((b >>> 0) & 0xFF);
+        write((b >>> 8) & 0xFF);
+    }
+
+    // Write 32 bit signed integer to stream
+    public void writeInt(int b) throws IOException {
+        write((b >>> 0) & 0xFF);
+        write((b >>> 8) & 0xFF);
+        write((b >>> 16) & 0xFF);
+        write((b >>> 24) & 0xFF);
+    }
+
+    // Write 64 bit signed integer to stream
+    public void writeLong(long b) throws IOException {
+        write((int) (b >>> 0) & 0xFF);
+        write((int) (b >>> 8) & 0xFF);
+        write((int) (b >>> 16) & 0xFF);
+        write((int) (b >>> 24) & 0xFF);
+        write((int) (b >>> 32) & 0xFF);
+        write((int) (b >>> 40) & 0xFF);
+        write((int) (b >>> 48) & 0xFF);
+        write((int) (b >>> 56) & 0xFF);
+    }
+
+    // Write 8 bit unsigned integer to stream
+    public void writeUnsignedByte(int b) throws IOException {
+        writeByte((byte) b);
+    }
+
+    // Write 16 bit unsigned integer to stream
+    public void writeUnsignedShort(int b) throws IOException {
+        writeShort((short) b);
+    }
+
+    // Write 32 bit unsigned integer to stream
+    public void writeUnsignedInt(long b) throws IOException {
+        writeInt((int) b);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2GlobalRegion.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2GlobalRegion.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,33 +1,33 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Soundfont global region.
- *
- * @author Karl Helgason
- */
-public class SF2GlobalRegion extends SF2Region {
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont global region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2GlobalRegion extends SF2Region {
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Instrument.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Instrument.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,911 +1,911 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.sound.midi.Patch;
-
-/**
- * Soundfont instrument.
- *
- * @author Karl Helgason
- */
-public class SF2Instrument extends ModelInstrument {
-
-    protected String name = "";
-    protected int preset = 0;
-    protected int bank = 0;
-    protected long library = 0;
-    protected long genre = 0;
-    protected long morphology = 0;
-    protected SF2GlobalRegion globalregion = null;
-    protected List<SF2InstrumentRegion> regions
-            = new ArrayList<SF2InstrumentRegion>();
-
-    public SF2Instrument() {
-        super(null, null, null, null);
-    }
-
-    public SF2Instrument(SF2Soundbank soundbank) {
-        super(soundbank, null, null, null);
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public Patch getPatch() {
-        if (bank == 128)
-            return new ModelPatch(0, preset, true);
-        else
-            return new ModelPatch(bank << 7, preset, false);
-    }
-
-    public void setPatch(Patch patch) {
-        if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) {
-            bank = 128;
-            preset = patch.getProgram();
-        } else {
-            bank = patch.getBank() >> 7;
-            preset = patch.getProgram();
-        }
-    }
-
-    public Object getData() {
-        return null;
-    }
-
-    public long getGenre() {
-        return genre;
-    }
-
-    public void setGenre(long genre) {
-        this.genre = genre;
-    }
-
-    public long getLibrary() {
-        return library;
-    }
-
-    public void setLibrary(long library) {
-        this.library = library;
-    }
-
-    public long getMorphology() {
-        return morphology;
-    }
-
-    public void setMorphology(long morphology) {
-        this.morphology = morphology;
-    }
-
-    public List<SF2InstrumentRegion> getRegions() {
-        return regions;
-    }
-
-    public SF2GlobalRegion getGlobalRegion() {
-        return globalregion;
-    }
-
-    public void setGlobalZone(SF2GlobalRegion zone) {
-        globalregion = zone;
-    }
-
-    public String toString() {
-        if (bank == 128)
-            return "Drumkit: " + name + " preset #" + preset;
-        else
-            return "Instrument: " + name + " bank #" + bank
-                    + " preset #" + preset;
-    }
-
-    public ModelPerformer[] getPerformers() {
-        int performercount = 0;
-        for (SF2InstrumentRegion presetzone : regions)
-            performercount += presetzone.getLayer().getRegions().size();
-        ModelPerformer[] performers = new ModelPerformer[performercount];
-        int pi = 0;
-
-        SF2GlobalRegion presetglobal = globalregion;
-        for (SF2InstrumentRegion presetzone : regions) {
-            Map<Integer, Short> pgenerators = new HashMap<Integer, Short>();
-            pgenerators.putAll(presetzone.getGenerators());
-            if (presetglobal != null)
-                pgenerators.putAll(presetglobal.getGenerators());
-
-            SF2Layer layer = presetzone.getLayer();
-            SF2GlobalRegion layerglobal = layer.getGlobalRegion();
-            for (SF2LayerRegion layerzone : layer.getRegions()) {
-                ModelPerformer performer = new ModelPerformer();
-                if (layerzone.getSample() != null)
-                    performer.setName(layerzone.getSample().getName());
-                else
-                    performer.setName(layer.getName());
-
-                performers[pi++] = performer;
-
-                int keyfrom = 0;
-                int keyto = 127;
-                int velfrom = 0;
-                int velto = 127;
-
-                if (layerzone.contains(SF2Region.GENERATOR_EXCLUSIVECLASS)) {
-                    performer.setExclusiveClass(layerzone.getInteger(
-                            SF2Region.GENERATOR_EXCLUSIVECLASS));
-                }
-                if (layerzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
-                    byte[] bytes = layerzone.getBytes(
-                            SF2Region.GENERATOR_KEYRANGE);
-                    if (bytes[0] >= 0)
-                        if (bytes[0] > keyfrom)
-                            keyfrom = bytes[0];
-                    if (bytes[1] >= 0)
-                        if (bytes[1] < keyto)
-                            keyto = bytes[1];
-                }
-                if (layerzone.contains(SF2Region.GENERATOR_VELRANGE)) {
-                    byte[] bytes = layerzone.getBytes(
-                            SF2Region.GENERATOR_VELRANGE);
-                    if (bytes[0] >= 0)
-                        if (bytes[0] > velfrom)
-                            velfrom = bytes[0];
-                    if (bytes[1] >= 0)
-                        if (bytes[1] < velto)
-                            velto = bytes[1];
-                }
-                if (presetzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
-                    byte[] bytes = presetzone.getBytes(
-                            SF2Region.GENERATOR_KEYRANGE);
-                    if (bytes[0] > keyfrom)
-                        keyfrom = bytes[0];
-                    if (bytes[1] < keyto)
-                        keyto = bytes[1];
-                }
-                if (presetzone.contains(SF2Region.GENERATOR_VELRANGE)) {
-                    byte[] bytes = presetzone.getBytes(
-                            SF2Region.GENERATOR_VELRANGE);
-                    if (bytes[0] > velfrom)
-                        velfrom = bytes[0];
-                    if (bytes[1] < velto)
-                        velto = bytes[1];
-                }
-                performer.setKeyFrom(keyfrom);
-                performer.setKeyTo(keyto);
-                performer.setVelFrom(velfrom);
-                performer.setVelTo(velto);
-
-                int startAddrsOffset = layerzone.getShort(
-                        SF2Region.GENERATOR_STARTADDRSOFFSET);
-                int endAddrsOffset = layerzone.getShort(
-                        SF2Region.GENERATOR_ENDADDRSOFFSET);
-                int startloopAddrsOffset = layerzone.getShort(
-                        SF2Region.GENERATOR_STARTLOOPADDRSOFFSET);
-                int endloopAddrsOffset = layerzone.getShort(
-                        SF2Region.GENERATOR_ENDLOOPADDRSOFFSET);
-
-                startAddrsOffset += layerzone.getShort(
-                        SF2Region.GENERATOR_STARTADDRSCOARSEOFFSET) * 32768;
-                endAddrsOffset += layerzone.getShort(
-                        SF2Region.GENERATOR_ENDADDRSCOARSEOFFSET) * 32768;
-                startloopAddrsOffset += layerzone.getShort(
-                        SF2Region.GENERATOR_STARTLOOPADDRSCOARSEOFFSET) * 32768;
-                endloopAddrsOffset += layerzone.getShort(
-                        SF2Region.GENERATOR_ENDLOOPADDRSCOARSEOFFSET) * 32768;
-                startloopAddrsOffset -= startAddrsOffset;
-                endloopAddrsOffset -= startAddrsOffset;
-
-                SF2Sample sample = layerzone.getSample();
-                int rootkey = sample.originalPitch;
-                if (layerzone.getShort(SF2Region.GENERATOR_OVERRIDINGROOTKEY) != -1) {
-                    rootkey = layerzone.getShort(
-                            SF2Region.GENERATOR_OVERRIDINGROOTKEY);
-                }
-                float pitchcorrection = (-rootkey * 100) + sample.pitchCorrection;
-                ModelByteBuffer buff = sample.getDataBuffer();
-                ModelByteBuffer buff24 = sample.getData24Buffer();
-
-                if (startAddrsOffset != 0 || endAddrsOffset != 0) {
-                    buff = buff.subbuffer(startAddrsOffset * 2,
-                            buff.capacity() + endAddrsOffset * 2);
-                    if (buff24 != null) {
-                        buff24 = buff24.subbuffer(startAddrsOffset,
-                                buff24.capacity() + endAddrsOffset);
-                    }
-
-                    /*
-                    if (startAddrsOffset < 0)
-                        startAddrsOffset = 0;
-                    if (endAddrsOffset > (buff.capacity()/2-startAddrsOffset))
-                        startAddrsOffset = (int)buff.capacity()/2-startAddrsOffset;
-                    byte[] data = buff.array();
-                    int off = (int)buff.arrayOffset() + startAddrsOffset*2;
-                    int len = (int)buff.capacity() + endAddrsOffset*2;
-                    if (off+len > data.length)
-                        len = data.length - off;
-                    buff = new ModelByteBuffer(data, off, len);
-                    if(buff24 != null) {
-                        data = buff.array();
-                        off = (int)buff.arrayOffset() + startAddrsOffset;
-                        len = (int)buff.capacity() + endAddrsOffset;
-                        buff24 = new ModelByteBuffer(data, off, len);
-                    }
-                    */
-                }
-
-                ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
-                        buff, sample.getFormat(), pitchcorrection);
-                if (buff24 != null)
-                    osc.set8BitExtensionBuffer(buff24);
-
-                Map<Integer, Short> generators = new HashMap<Integer, Short>();
-                if (layerglobal != null)
-                    generators.putAll(layerglobal.getGenerators());
-                generators.putAll(layerzone.getGenerators());
-                for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) {
-                    short val;
-                    if (!generators.containsKey(gen.getKey()))
-                        val = layerzone.getShort(gen.getKey());
-                    else
-                        val = generators.get(gen.getKey());
-                    val += gen.getValue();
-                    generators.put(gen.getKey(), val);
-                }
-
-                // SampleMode:
-                // 0 indicates a sound reproduced with no loop
-                // 1 indicates a sound which loops continuously
-                // 2 is unused but should be interpreted as indicating no loop
-                // 3 indicates a sound which loops for the duration of key
-                //   depression then proceeds to play the remainder of the sample.
-                int sampleMode = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_SAMPLEMODES);
-                if ((sampleMode == 1) || (sampleMode == 3)) {
-                    if (sample.startLoop >= 0 && sample.endLoop > 0) {
-                        osc.setLoopStart((int)(sample.startLoop
-                                + startloopAddrsOffset));
-                        osc.setLoopLength((int)(sample.endLoop - sample.startLoop
-                                + endloopAddrsOffset - startloopAddrsOffset));
-                        if (sampleMode == 1)
-                            osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
-                        if (sampleMode == 3)
-                            osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
-                    }
-                }
-                performer.getOscillators().add(osc);
-
-
-                short volDelay = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_DELAYVOLENV);
-                short volAttack = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_ATTACKVOLENV);
-                short volHold = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_HOLDVOLENV);
-                short volDecay = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_DECAYVOLENV);
-                short volSustain = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_SUSTAINVOLENV);
-                short volRelease = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_RELEASEVOLENV);
-
-                if (volHold != -12000) {
-                    short volKeyNumToHold = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_KEYNUMTOVOLENVHOLD);
-                    volHold += 60 * volKeyNumToHold;
-                    float fvalue = -volKeyNumToHold * 128;
-                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_EG1_HOLD;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(new ModelSource(src), fvalue,
-                            new ModelDestination(dest)));
-                }
-                if (volDecay != -12000) {
-                    short volKeyNumToDecay = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_KEYNUMTOVOLENVDECAY);
-                    volDecay += 60 * volKeyNumToDecay;
-                    float fvalue = -volKeyNumToDecay * 128;
-                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_EG1_DECAY;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(new ModelSource(src), fvalue,
-                            new ModelDestination(dest)));
-                }
-
-                addTimecentValue(performer,
-                        ModelDestination.DESTINATION_EG1_DELAY, volDelay);
-                addTimecentValue(performer,
-                        ModelDestination.DESTINATION_EG1_ATTACK, volAttack);
-                addTimecentValue(performer,
-                        ModelDestination.DESTINATION_EG1_HOLD, volHold);
-                addTimecentValue(performer,
-                        ModelDestination.DESTINATION_EG1_DECAY, volDecay);
-                //float fvolsustain = (960-volSustain)*(1000.0f/960.0f);
-
-                volSustain = (short)(1000 - volSustain);
-                if (volSustain < 0)
-                    volSustain = 0;
-                if (volSustain > 1000)
-                    volSustain = 1000;
-
-                addValue(performer,
-                        ModelDestination.DESTINATION_EG1_SUSTAIN, volSustain);
-                addTimecentValue(performer,
-                        ModelDestination.DESTINATION_EG1_RELEASE, volRelease);
-
-                if (getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODENVTOFILTERFC) != 0
-                        || getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
-                    short modDelay = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_DELAYMODENV);
-                    short modAttack = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_ATTACKMODENV);
-                    short modHold = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_HOLDMODENV);
-                    short modDecay = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_DECAYMODENV);
-                    short modSustain = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_SUSTAINMODENV);
-                    short modRelease = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_RELEASEMODENV);
-
-
-                    if (modHold != -12000) {
-                        short modKeyNumToHold = getGeneratorValue(generators,
-                                SF2Region.GENERATOR_KEYNUMTOMODENVHOLD);
-                        modHold += 60 * modKeyNumToHold;
-                        float fvalue = -modKeyNumToHold * 128;
-                        ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
-                        ModelIdentifier dest = ModelDestination.DESTINATION_EG2_HOLD;
-                        performer.getConnectionBlocks().add(
-                            new ModelConnectionBlock(new ModelSource(src),
-                                fvalue, new ModelDestination(dest)));
-                    }
-                    if (modDecay != -12000) {
-                        short modKeyNumToDecay = getGeneratorValue(generators,
-                                SF2Region.GENERATOR_KEYNUMTOMODENVDECAY);
-                        modDecay += 60 * modKeyNumToDecay;
-                        float fvalue = -modKeyNumToDecay * 128;
-                        ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
-                        ModelIdentifier dest = ModelDestination.DESTINATION_EG2_DECAY;
-                        performer.getConnectionBlocks().add(
-                            new ModelConnectionBlock(new ModelSource(src),
-                                fvalue, new ModelDestination(dest)));
-                    }
-
-                    addTimecentValue(performer,
-                            ModelDestination.DESTINATION_EG2_DELAY, modDelay);
-                    addTimecentValue(performer,
-                            ModelDestination.DESTINATION_EG2_ATTACK, modAttack);
-                    addTimecentValue(performer,
-                            ModelDestination.DESTINATION_EG2_HOLD, modHold);
-                    addTimecentValue(performer,
-                            ModelDestination.DESTINATION_EG2_DECAY, modDecay);
-                    if (modSustain < 0)
-                        modSustain = 0;
-                    if (modSustain > 1000)
-                        modSustain = 1000;
-                    addValue(performer, ModelDestination.DESTINATION_EG2_SUSTAIN,
-                            1000 - modSustain);
-                    addTimecentValue(performer,
-                            ModelDestination.DESTINATION_EG2_RELEASE, modRelease);
-
-                    if (getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODENVTOFILTERFC) != 0) {
-                        double fvalue = getGeneratorValue(generators,
-                                SF2Region.GENERATOR_MODENVTOFILTERFC);
-                        ModelIdentifier src = ModelSource.SOURCE_EG2;
-                        ModelIdentifier dest
-                                = ModelDestination.DESTINATION_FILTER_FREQ;
-                        performer.getConnectionBlocks().add(
-                            new ModelConnectionBlock(new ModelSource(src),
-                                fvalue, new ModelDestination(dest)));
-                    }
-
-                    if (getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
-                        double fvalue = getGeneratorValue(generators,
-                                SF2Region.GENERATOR_MODENVTOPITCH);
-                        ModelIdentifier src = ModelSource.SOURCE_EG2;
-                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
-                        performer.getConnectionBlocks().add(
-                            new ModelConnectionBlock(new ModelSource(src),
-                                fvalue, new ModelDestination(dest)));
-                    }
-
-                }
-
-                if (getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0
-                        || getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODLFOTOPITCH) != 0
-                        || getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
-                    short lfo_freq = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_FREQMODLFO);
-                    short lfo_delay = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_DELAYMODLFO);
-                    addTimecentValue(performer,
-                            ModelDestination.DESTINATION_LFO1_DELAY, lfo_delay);
-                    addValue(performer,
-                            ModelDestination.DESTINATION_LFO1_FREQ, lfo_freq);
-                }
-
-                short vib_freq = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_FREQVIBLFO);
-                short vib_delay = getGeneratorValue(generators,
-                        SF2Region.GENERATOR_DELAYVIBLFO);
-                addTimecentValue(performer,
-                        ModelDestination.DESTINATION_LFO2_DELAY, vib_delay);
-                addValue(performer,
-                        ModelDestination.DESTINATION_LFO2_FREQ, vib_freq);
-
-
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_VIBLFOTOPITCH) != 0) {
-                    double fvalue = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_VIBLFOTOPITCH);
-                    ModelIdentifier src = ModelSource.SOURCE_LFO2;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(
-                            new ModelSource(src,
-                                ModelStandardTransform.DIRECTION_MIN2MAX,
-                                ModelStandardTransform.POLARITY_BIPOLAR),
-                            fvalue, new ModelDestination(dest)));
-                }
-
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0) {
-                    double fvalue = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODLFOTOFILTERFC);
-                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_FILTER_FREQ;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(
-                            new ModelSource(src,
-                                ModelStandardTransform.DIRECTION_MIN2MAX,
-                                ModelStandardTransform.POLARITY_BIPOLAR),
-                            fvalue, new ModelDestination(dest)));
-                }
-
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_MODLFOTOPITCH) != 0) {
-                    double fvalue = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODLFOTOPITCH);
-                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(
-                            new ModelSource(src,
-                                ModelStandardTransform.DIRECTION_MIN2MAX,
-                                ModelStandardTransform.POLARITY_BIPOLAR),
-                            fvalue, new ModelDestination(dest)));
-                }
-
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
-                    double fvalue = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_MODLFOTOVOLUME);
-                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_GAIN;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(
-                            new ModelSource(src,
-                                ModelStandardTransform.DIRECTION_MIN2MAX,
-                                ModelStandardTransform.POLARITY_BIPOLAR),
-                            fvalue, new ModelDestination(dest)));
-                }
-
-                if (layerzone.getShort(SF2Region.GENERATOR_KEYNUM) != -1) {
-                    double val = layerzone.getShort(SF2Region.GENERATOR_KEYNUM)/128.0;
-                    addValue(performer, ModelDestination.DESTINATION_KEYNUMBER, val);
-                }
-
-                if (layerzone.getShort(SF2Region.GENERATOR_VELOCITY) != -1) {
-                    double val = layerzone.getShort(SF2Region.GENERATOR_VELOCITY)
-                                 / 128.0;
-                    addValue(performer, ModelDestination.DESTINATION_VELOCITY, val);
-                }
-
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_INITIALFILTERFC) < 13500) {
-                    short filter_freq = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_INITIALFILTERFC);
-                    short filter_q = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_INITIALFILTERQ);
-                    addValue(performer,
-                            ModelDestination.DESTINATION_FILTER_FREQ, filter_freq);
-                    addValue(performer,
-                            ModelDestination.DESTINATION_FILTER_Q, filter_q);
-                }
-
-                int tune = 100 * getGeneratorValue(generators,
-                        SF2Region.GENERATOR_COARSETUNE);
-                tune += getGeneratorValue(generators,
-                        SF2Region.GENERATOR_FINETUNE);
-                if (tune != 0) {
-                    addValue(performer,
-                            ModelDestination.DESTINATION_PITCH, (short) tune);
-                }
-                if (getGeneratorValue(generators, SF2Region.GENERATOR_PAN) != 0) {
-                    short val = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_PAN);
-                    addValue(performer, ModelDestination.DESTINATION_PAN, val);
-                }
-                if (getGeneratorValue(generators, SF2Region.GENERATOR_INITIALATTENUATION) != 0) {
-                    short val = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_INITIALATTENUATION);
-                    addValue(performer,
-                            ModelDestination.DESTINATION_GAIN, -0.376287f * val);
-                }
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_CHORUSEFFECTSSEND) != 0) {
-                    short val = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_CHORUSEFFECTSSEND);
-                    addValue(performer, ModelDestination.DESTINATION_CHORUS, val);
-                }
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_REVERBEFFECTSSEND) != 0) {
-                    short val = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_REVERBEFFECTSSEND);
-                    addValue(performer, ModelDestination.DESTINATION_REVERB, val);
-                }
-                if (getGeneratorValue(generators,
-                        SF2Region.GENERATOR_SCALETUNING) != 100) {
-                    short fvalue = getGeneratorValue(generators,
-                            SF2Region.GENERATOR_SCALETUNING);
-                    if (fvalue == 0) {
-                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
-                        performer.getConnectionBlocks().add(
-                            new ModelConnectionBlock(null, rootkey * 100,
-                                new ModelDestination(dest)));
-                    } else {
-                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
-                        performer.getConnectionBlocks().add(
-                            new ModelConnectionBlock(null, rootkey * (100 - fvalue),
-                                new ModelDestination(dest)));
-                    }
-
-                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
-                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
-                    performer.getConnectionBlocks().add(
-                        new ModelConnectionBlock(new ModelSource(src),
-                            128 * fvalue, new ModelDestination(dest)));
-
-                }
-
-                performer.getConnectionBlocks().add(
-                    new ModelConnectionBlock(
-                        new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY,
-                            new ModelTransform() {
-                                public double transform(double value) {
-                                    if (value < 0.5)
-                                        return 1 - value * 2;
-                                    else
-                                        return 0;
-                                }
-                            }),
-                        -2400,
-                        new ModelDestination(
-                            ModelDestination.DESTINATION_FILTER_FREQ)));
-
-
-                performer.getConnectionBlocks().add(
-                    new ModelConnectionBlock(
-                        new ModelSource(ModelSource.SOURCE_LFO2,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_BIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_UNIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        50, new ModelDestination(
-                            ModelDestination.DESTINATION_PITCH)));
-
-                if (layer.getGlobalRegion() != null) {
-                    for (SF2Modulator modulator
-                            : layer.getGlobalRegion().getModulators()) {
-                        convertModulator(performer, modulator);
-                    }
-                }
-                for (SF2Modulator modulator : layerzone.getModulators())
-                    convertModulator(performer, modulator);
-
-                if (presetglobal != null) {
-                    for (SF2Modulator modulator : presetglobal.getModulators())
-                        convertModulator(performer, modulator);
-                }
-                for (SF2Modulator modulator : presetzone.getModulators())
-                    convertModulator(performer, modulator);
-
-            }
-        }
-        return performers;
-    }
-
-    private void convertModulator(ModelPerformer performer,
-            SF2Modulator modulator) {
-        ModelSource src1 = convertSource(modulator.getSourceOperator());
-        ModelSource src2 = convertSource(modulator.getAmountSourceOperator());
-        if (src1 == null && modulator.getSourceOperator() != 0)
-            return;
-        if (src2 == null && modulator.getAmountSourceOperator() != 0)
-            return;
-        double amount = modulator.getAmount();
-        double[] amountcorrection = new double[1];
-        ModelSource[] extrasrc = new ModelSource[1];
-        amountcorrection[0] = 1;
-        ModelDestination dst = convertDestination(
-                modulator.getDestinationOperator(), amountcorrection, extrasrc);
-        amount *= amountcorrection[0];
-        if (dst == null)
-            return;
-        if (modulator.getTransportOperator() == SF2Modulator.TRANSFORM_ABSOLUTE) {
-            ((ModelStandardTransform)dst.getTransform()).setTransform(
-                    ModelStandardTransform.TRANSFORM_ABSOLUTE);
-        }
-        ModelConnectionBlock conn = new ModelConnectionBlock(src1, src2, amount, dst);
-        if (extrasrc[0] != null)
-            conn.addSource(extrasrc[0]);
-        performer.getConnectionBlocks().add(conn);
-
-    }
-
-    private static ModelSource convertSource(int src) {
-        if (src == 0)
-            return null;
-        ModelIdentifier id = null;
-        int idsrc = src & 0x7F;
-        if ((src & SF2Modulator.SOURCE_MIDI_CONTROL) != 0) {
-            id = new ModelIdentifier("midi_cc", Integer.toString(idsrc));
-        } else {
-            if (idsrc == SF2Modulator.SOURCE_NOTE_ON_VELOCITY)
-                id = ModelSource.SOURCE_NOTEON_VELOCITY;
-            if (idsrc == SF2Modulator.SOURCE_NOTE_ON_KEYNUMBER)
-                id = ModelSource.SOURCE_NOTEON_KEYNUMBER;
-            if (idsrc == SF2Modulator.SOURCE_POLY_PRESSURE)
-                id = ModelSource.SOURCE_MIDI_POLY_PRESSURE;
-            if (idsrc == SF2Modulator.SOURCE_CHANNEL_PRESSURE)
-                id = ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
-            if (idsrc == SF2Modulator.SOURCE_PITCH_WHEEL)
-                id = ModelSource.SOURCE_MIDI_PITCH;
-            if (idsrc == SF2Modulator.SOURCE_PITCH_SENSITIVITY)
-                id = new ModelIdentifier("midi_rpn", "0");
-        }
-        if (id == null)
-            return null;
-
-        ModelSource msrc = new ModelSource(id);
-        ModelStandardTransform transform
-                = (ModelStandardTransform) msrc.getTransform();
-
-        if ((SF2Modulator.SOURCE_DIRECTION_MAX_MIN & src) != 0)
-            transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
-        else
-            transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
-
-        if ((SF2Modulator.SOURCE_POLARITY_BIPOLAR & src) != 0)
-            transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
-        else
-            transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
-
-        if ((SF2Modulator.SOURCE_TYPE_CONCAVE & src) != 0)
-            transform.setTransform(ModelStandardTransform.TRANSFORM_CONCAVE);
-        if ((SF2Modulator.SOURCE_TYPE_CONVEX & src) != 0)
-            transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX);
-        if ((SF2Modulator.SOURCE_TYPE_SWITCH & src) != 0)
-            transform.setTransform(ModelStandardTransform.TRANSFORM_SWITCH);
-
-        return msrc;
-    }
-
-    protected static ModelDestination convertDestination(int dst,
-            double[] amountcorrection, ModelSource[] extrasrc) {
-        ModelIdentifier id = null;
-        switch (dst) {
-            case SF2Region.GENERATOR_INITIALFILTERFC:
-                id = ModelDestination.DESTINATION_FILTER_FREQ;
-                break;
-            case SF2Region.GENERATOR_INITIALFILTERQ:
-                id = ModelDestination.DESTINATION_FILTER_Q;
-                break;
-            case SF2Region.GENERATOR_CHORUSEFFECTSSEND:
-                id = ModelDestination.DESTINATION_CHORUS;
-                break;
-            case SF2Region.GENERATOR_REVERBEFFECTSSEND:
-                id = ModelDestination.DESTINATION_REVERB;
-                break;
-            case SF2Region.GENERATOR_PAN:
-                id = ModelDestination.DESTINATION_PAN;
-                break;
-            case SF2Region.GENERATOR_DELAYMODLFO:
-                id = ModelDestination.DESTINATION_LFO1_DELAY;
-                break;
-            case SF2Region.GENERATOR_FREQMODLFO:
-                id = ModelDestination.DESTINATION_LFO1_FREQ;
-                break;
-            case SF2Region.GENERATOR_DELAYVIBLFO:
-                id = ModelDestination.DESTINATION_LFO2_DELAY;
-                break;
-            case SF2Region.GENERATOR_FREQVIBLFO:
-                id = ModelDestination.DESTINATION_LFO2_FREQ;
-                break;
-
-            case SF2Region.GENERATOR_DELAYMODENV:
-                id = ModelDestination.DESTINATION_EG2_DELAY;
-                break;
-            case SF2Region.GENERATOR_ATTACKMODENV:
-                id = ModelDestination.DESTINATION_EG2_ATTACK;
-                break;
-            case SF2Region.GENERATOR_HOLDMODENV:
-                id = ModelDestination.DESTINATION_EG2_HOLD;
-                break;
-            case SF2Region.GENERATOR_DECAYMODENV:
-                id = ModelDestination.DESTINATION_EG2_DECAY;
-                break;
-            case SF2Region.GENERATOR_SUSTAINMODENV:
-                id = ModelDestination.DESTINATION_EG2_SUSTAIN;
-                amountcorrection[0] = -1;
-                break;
-            case SF2Region.GENERATOR_RELEASEMODENV:
-                id = ModelDestination.DESTINATION_EG2_RELEASE;
-                break;
-            case SF2Region.GENERATOR_DELAYVOLENV:
-                id = ModelDestination.DESTINATION_EG1_DELAY;
-                break;
-            case SF2Region.GENERATOR_ATTACKVOLENV:
-                id = ModelDestination.DESTINATION_EG1_ATTACK;
-                break;
-            case SF2Region.GENERATOR_HOLDVOLENV:
-                id = ModelDestination.DESTINATION_EG1_HOLD;
-                break;
-            case SF2Region.GENERATOR_DECAYVOLENV:
-                id = ModelDestination.DESTINATION_EG1_DECAY;
-                break;
-            case SF2Region.GENERATOR_SUSTAINVOLENV:
-                id = ModelDestination.DESTINATION_EG1_SUSTAIN;
-                amountcorrection[0] = -1;
-                break;
-            case SF2Region.GENERATOR_RELEASEVOLENV:
-                id = ModelDestination.DESTINATION_EG1_RELEASE;
-                break;
-            case SF2Region.GENERATOR_KEYNUM:
-                id = ModelDestination.DESTINATION_KEYNUMBER;
-                break;
-            case SF2Region.GENERATOR_VELOCITY:
-                id = ModelDestination.DESTINATION_VELOCITY;
-                break;
-
-            case SF2Region.GENERATOR_COARSETUNE:
-                amountcorrection[0] = 100;
-                id = ModelDestination.DESTINATION_PITCH;
-                break;
-
-            case SF2Region.GENERATOR_FINETUNE:
-                id = ModelDestination.DESTINATION_PITCH;
-                break;
-
-            case SF2Region.GENERATOR_INITIALATTENUATION:
-                id = ModelDestination.DESTINATION_GAIN;
-                amountcorrection[0] = -0.376287f;
-                break;
-
-            case SF2Region.GENERATOR_VIBLFOTOPITCH:
-                id = ModelDestination.DESTINATION_PITCH;
-                extrasrc[0] = new ModelSource(
-                        ModelSource.SOURCE_LFO2,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR);
-                break;
-
-            case SF2Region.GENERATOR_MODLFOTOPITCH:
-                id = ModelDestination.DESTINATION_PITCH;
-                extrasrc[0] = new ModelSource(
-                        ModelSource.SOURCE_LFO1,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR);
-                break;
-
-            case SF2Region.GENERATOR_MODLFOTOFILTERFC:
-                id = ModelDestination.DESTINATION_FILTER_FREQ;
-                extrasrc[0] = new ModelSource(
-                        ModelSource.SOURCE_LFO1,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR);
-                break;
-
-            case SF2Region.GENERATOR_MODLFOTOVOLUME:
-                id = ModelDestination.DESTINATION_GAIN;
-                amountcorrection[0] = -0.376287f;
-                extrasrc[0] = new ModelSource(
-                        ModelSource.SOURCE_LFO1,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR);
-                break;
-
-            case SF2Region.GENERATOR_MODENVTOPITCH:
-                id = ModelDestination.DESTINATION_PITCH;
-                extrasrc[0] = new ModelSource(
-                        ModelSource.SOURCE_EG2,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR);
-                break;
-
-            case SF2Region.GENERATOR_MODENVTOFILTERFC:
-                id = ModelDestination.DESTINATION_FILTER_FREQ;
-                extrasrc[0] = new ModelSource(
-                        ModelSource.SOURCE_EG2,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR);
-                break;
-
-            default:
-                break;
-        }
-        if (id != null)
-            return new ModelDestination(id);
-        return null;
-    }
-
-    private void addTimecentValue(ModelPerformer performer,
-            ModelIdentifier dest, short value) {
-        double fvalue;
-        if (value == -12000)
-            fvalue = Double.NEGATIVE_INFINITY;
-        else
-            fvalue = value;
-        performer.getConnectionBlocks().add(
-                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
-    }
-
-    private void addValue(ModelPerformer performer,
-            ModelIdentifier dest, short value) {
-        double fvalue = value;
-        performer.getConnectionBlocks().add(
-                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
-    }
-
-    private void addValue(ModelPerformer performer,
-            ModelIdentifier dest, double value) {
-        double fvalue = value;
-        performer.getConnectionBlocks().add(
-                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
-    }
-
-    private short getGeneratorValue(Map<Integer, Short> generators, int gen) {
-        if (generators.containsKey(gen))
-            return generators.get(gen);
-        return SF2Region.getDefaultValue(gen);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Patch;
+
+/**
+ * Soundfont instrument.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Instrument extends ModelInstrument {
+
+    protected String name = "";
+    protected int preset = 0;
+    protected int bank = 0;
+    protected long library = 0;
+    protected long genre = 0;
+    protected long morphology = 0;
+    protected SF2GlobalRegion globalregion = null;
+    protected List<SF2InstrumentRegion> regions
+            = new ArrayList<SF2InstrumentRegion>();
+
+    public SF2Instrument() {
+        super(null, null, null, null);
+    }
+
+    public SF2Instrument(SF2Soundbank soundbank) {
+        super(soundbank, null, null, null);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Patch getPatch() {
+        if (bank == 128)
+            return new ModelPatch(0, preset, true);
+        else
+            return new ModelPatch(bank << 7, preset, false);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion()) {
+            bank = 128;
+            preset = patch.getProgram();
+        } else {
+            bank = patch.getBank() >> 7;
+            preset = patch.getProgram();
+        }
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public long getGenre() {
+        return genre;
+    }
+
+    public void setGenre(long genre) {
+        this.genre = genre;
+    }
+
+    public long getLibrary() {
+        return library;
+    }
+
+    public void setLibrary(long library) {
+        this.library = library;
+    }
+
+    public long getMorphology() {
+        return morphology;
+    }
+
+    public void setMorphology(long morphology) {
+        this.morphology = morphology;
+    }
+
+    public List<SF2InstrumentRegion> getRegions() {
+        return regions;
+    }
+
+    public SF2GlobalRegion getGlobalRegion() {
+        return globalregion;
+    }
+
+    public void setGlobalZone(SF2GlobalRegion zone) {
+        globalregion = zone;
+    }
+
+    public String toString() {
+        if (bank == 128)
+            return "Drumkit: " + name + " preset #" + preset;
+        else
+            return "Instrument: " + name + " bank #" + bank
+                    + " preset #" + preset;
+    }
+
+    public ModelPerformer[] getPerformers() {
+        int performercount = 0;
+        for (SF2InstrumentRegion presetzone : regions)
+            performercount += presetzone.getLayer().getRegions().size();
+        ModelPerformer[] performers = new ModelPerformer[performercount];
+        int pi = 0;
+
+        SF2GlobalRegion presetglobal = globalregion;
+        for (SF2InstrumentRegion presetzone : regions) {
+            Map<Integer, Short> pgenerators = new HashMap<Integer, Short>();
+            pgenerators.putAll(presetzone.getGenerators());
+            if (presetglobal != null)
+                pgenerators.putAll(presetglobal.getGenerators());
+
+            SF2Layer layer = presetzone.getLayer();
+            SF2GlobalRegion layerglobal = layer.getGlobalRegion();
+            for (SF2LayerRegion layerzone : layer.getRegions()) {
+                ModelPerformer performer = new ModelPerformer();
+                if (layerzone.getSample() != null)
+                    performer.setName(layerzone.getSample().getName());
+                else
+                    performer.setName(layer.getName());
+
+                performers[pi++] = performer;
+
+                int keyfrom = 0;
+                int keyto = 127;
+                int velfrom = 0;
+                int velto = 127;
+
+                if (layerzone.contains(SF2Region.GENERATOR_EXCLUSIVECLASS)) {
+                    performer.setExclusiveClass(layerzone.getInteger(
+                            SF2Region.GENERATOR_EXCLUSIVECLASS));
+                }
+                if (layerzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
+                    byte[] bytes = layerzone.getBytes(
+                            SF2Region.GENERATOR_KEYRANGE);
+                    if (bytes[0] >= 0)
+                        if (bytes[0] > keyfrom)
+                            keyfrom = bytes[0];
+                    if (bytes[1] >= 0)
+                        if (bytes[1] < keyto)
+                            keyto = bytes[1];
+                }
+                if (layerzone.contains(SF2Region.GENERATOR_VELRANGE)) {
+                    byte[] bytes = layerzone.getBytes(
+                            SF2Region.GENERATOR_VELRANGE);
+                    if (bytes[0] >= 0)
+                        if (bytes[0] > velfrom)
+                            velfrom = bytes[0];
+                    if (bytes[1] >= 0)
+                        if (bytes[1] < velto)
+                            velto = bytes[1];
+                }
+                if (presetzone.contains(SF2Region.GENERATOR_KEYRANGE)) {
+                    byte[] bytes = presetzone.getBytes(
+                            SF2Region.GENERATOR_KEYRANGE);
+                    if (bytes[0] > keyfrom)
+                        keyfrom = bytes[0];
+                    if (bytes[1] < keyto)
+                        keyto = bytes[1];
+                }
+                if (presetzone.contains(SF2Region.GENERATOR_VELRANGE)) {
+                    byte[] bytes = presetzone.getBytes(
+                            SF2Region.GENERATOR_VELRANGE);
+                    if (bytes[0] > velfrom)
+                        velfrom = bytes[0];
+                    if (bytes[1] < velto)
+                        velto = bytes[1];
+                }
+                performer.setKeyFrom(keyfrom);
+                performer.setKeyTo(keyto);
+                performer.setVelFrom(velfrom);
+                performer.setVelTo(velto);
+
+                int startAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_STARTADDRSOFFSET);
+                int endAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_ENDADDRSOFFSET);
+                int startloopAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_STARTLOOPADDRSOFFSET);
+                int endloopAddrsOffset = layerzone.getShort(
+                        SF2Region.GENERATOR_ENDLOOPADDRSOFFSET);
+
+                startAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_STARTADDRSCOARSEOFFSET) * 32768;
+                endAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_ENDADDRSCOARSEOFFSET) * 32768;
+                startloopAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_STARTLOOPADDRSCOARSEOFFSET) * 32768;
+                endloopAddrsOffset += layerzone.getShort(
+                        SF2Region.GENERATOR_ENDLOOPADDRSCOARSEOFFSET) * 32768;
+                startloopAddrsOffset -= startAddrsOffset;
+                endloopAddrsOffset -= startAddrsOffset;
+
+                SF2Sample sample = layerzone.getSample();
+                int rootkey = sample.originalPitch;
+                if (layerzone.getShort(SF2Region.GENERATOR_OVERRIDINGROOTKEY) != -1) {
+                    rootkey = layerzone.getShort(
+                            SF2Region.GENERATOR_OVERRIDINGROOTKEY);
+                }
+                float pitchcorrection = (-rootkey * 100) + sample.pitchCorrection;
+                ModelByteBuffer buff = sample.getDataBuffer();
+                ModelByteBuffer buff24 = sample.getData24Buffer();
+
+                if (startAddrsOffset != 0 || endAddrsOffset != 0) {
+                    buff = buff.subbuffer(startAddrsOffset * 2,
+                            buff.capacity() + endAddrsOffset * 2);
+                    if (buff24 != null) {
+                        buff24 = buff24.subbuffer(startAddrsOffset,
+                                buff24.capacity() + endAddrsOffset);
+                    }
+
+                    /*
+                    if (startAddrsOffset < 0)
+                        startAddrsOffset = 0;
+                    if (endAddrsOffset > (buff.capacity()/2-startAddrsOffset))
+                        startAddrsOffset = (int)buff.capacity()/2-startAddrsOffset;
+                    byte[] data = buff.array();
+                    int off = (int)buff.arrayOffset() + startAddrsOffset*2;
+                    int len = (int)buff.capacity() + endAddrsOffset*2;
+                    if (off+len > data.length)
+                        len = data.length - off;
+                    buff = new ModelByteBuffer(data, off, len);
+                    if(buff24 != null) {
+                        data = buff.array();
+                        off = (int)buff.arrayOffset() + startAddrsOffset;
+                        len = (int)buff.capacity() + endAddrsOffset;
+                        buff24 = new ModelByteBuffer(data, off, len);
+                    }
+                    */
+                }
+
+                ModelByteBufferWavetable osc = new ModelByteBufferWavetable(
+                        buff, sample.getFormat(), pitchcorrection);
+                if (buff24 != null)
+                    osc.set8BitExtensionBuffer(buff24);
+
+                Map<Integer, Short> generators = new HashMap<Integer, Short>();
+                if (layerglobal != null)
+                    generators.putAll(layerglobal.getGenerators());
+                generators.putAll(layerzone.getGenerators());
+                for (Map.Entry<Integer, Short> gen : pgenerators.entrySet()) {
+                    short val;
+                    if (!generators.containsKey(gen.getKey()))
+                        val = layerzone.getShort(gen.getKey());
+                    else
+                        val = generators.get(gen.getKey());
+                    val += gen.getValue();
+                    generators.put(gen.getKey(), val);
+                }
+
+                // SampleMode:
+                // 0 indicates a sound reproduced with no loop
+                // 1 indicates a sound which loops continuously
+                // 2 is unused but should be interpreted as indicating no loop
+                // 3 indicates a sound which loops for the duration of key
+                //   depression then proceeds to play the remainder of the sample.
+                int sampleMode = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_SAMPLEMODES);
+                if ((sampleMode == 1) || (sampleMode == 3)) {
+                    if (sample.startLoop >= 0 && sample.endLoop > 0) {
+                        osc.setLoopStart((int)(sample.startLoop
+                                + startloopAddrsOffset));
+                        osc.setLoopLength((int)(sample.endLoop - sample.startLoop
+                                + endloopAddrsOffset - startloopAddrsOffset));
+                        if (sampleMode == 1)
+                            osc.setLoopType(ModelWavetable.LOOP_TYPE_FORWARD);
+                        if (sampleMode == 3)
+                            osc.setLoopType(ModelWavetable.LOOP_TYPE_RELEASE);
+                    }
+                }
+                performer.getOscillators().add(osc);
+
+
+                short volDelay = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_DELAYVOLENV);
+                short volAttack = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_ATTACKVOLENV);
+                short volHold = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_HOLDVOLENV);
+                short volDecay = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_DECAYVOLENV);
+                short volSustain = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_SUSTAINVOLENV);
+                short volRelease = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_RELEASEVOLENV);
+
+                if (volHold != -12000) {
+                    short volKeyNumToHold = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_KEYNUMTOVOLENVHOLD);
+                    volHold += 60 * volKeyNumToHold;
+                    float fvalue = -volKeyNumToHold * 128;
+                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_EG1_HOLD;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(new ModelSource(src), fvalue,
+                            new ModelDestination(dest)));
+                }
+                if (volDecay != -12000) {
+                    short volKeyNumToDecay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_KEYNUMTOVOLENVDECAY);
+                    volDecay += 60 * volKeyNumToDecay;
+                    float fvalue = -volKeyNumToDecay * 128;
+                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_EG1_DECAY;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(new ModelSource(src), fvalue,
+                            new ModelDestination(dest)));
+                }
+
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_DELAY, volDelay);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_ATTACK, volAttack);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_HOLD, volHold);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_DECAY, volDecay);
+                //float fvolsustain = (960-volSustain)*(1000.0f/960.0f);
+
+                volSustain = (short)(1000 - volSustain);
+                if (volSustain < 0)
+                    volSustain = 0;
+                if (volSustain > 1000)
+                    volSustain = 1000;
+
+                addValue(performer,
+                        ModelDestination.DESTINATION_EG1_SUSTAIN, volSustain);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_EG1_RELEASE, volRelease);
+
+                if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOFILTERFC) != 0
+                        || getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
+                    short modDelay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_DELAYMODENV);
+                    short modAttack = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_ATTACKMODENV);
+                    short modHold = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_HOLDMODENV);
+                    short modDecay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_DECAYMODENV);
+                    short modSustain = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_SUSTAINMODENV);
+                    short modRelease = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_RELEASEMODENV);
+
+
+                    if (modHold != -12000) {
+                        short modKeyNumToHold = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_KEYNUMTOMODENVHOLD);
+                        modHold += 60 * modKeyNumToHold;
+                        float fvalue = -modKeyNumToHold * 128;
+                        ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                        ModelIdentifier dest = ModelDestination.DESTINATION_EG2_HOLD;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+                    if (modDecay != -12000) {
+                        short modKeyNumToDecay = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_KEYNUMTOMODENVDECAY);
+                        modDecay += 60 * modKeyNumToDecay;
+                        float fvalue = -modKeyNumToDecay * 128;
+                        ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                        ModelIdentifier dest = ModelDestination.DESTINATION_EG2_DECAY;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_DELAY, modDelay);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_ATTACK, modAttack);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_HOLD, modHold);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_DECAY, modDecay);
+                    if (modSustain < 0)
+                        modSustain = 0;
+                    if (modSustain > 1000)
+                        modSustain = 1000;
+                    addValue(performer, ModelDestination.DESTINATION_EG2_SUSTAIN,
+                            1000 - modSustain);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_EG2_RELEASE, modRelease);
+
+                    if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOFILTERFC) != 0) {
+                        double fvalue = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_MODENVTOFILTERFC);
+                        ModelIdentifier src = ModelSource.SOURCE_EG2;
+                        ModelIdentifier dest
+                                = ModelDestination.DESTINATION_FILTER_FREQ;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+
+                    if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODENVTOPITCH) != 0) {
+                        double fvalue = getGeneratorValue(generators,
+                                SF2Region.GENERATOR_MODENVTOPITCH);
+                        ModelIdentifier src = ModelSource.SOURCE_EG2;
+                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(new ModelSource(src),
+                                fvalue, new ModelDestination(dest)));
+                    }
+
+                }
+
+                if (getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0
+                        || getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOPITCH) != 0
+                        || getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
+                    short lfo_freq = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_FREQMODLFO);
+                    short lfo_delay = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_DELAYMODLFO);
+                    addTimecentValue(performer,
+                            ModelDestination.DESTINATION_LFO1_DELAY, lfo_delay);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_LFO1_FREQ, lfo_freq);
+                }
+
+                short vib_freq = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_FREQVIBLFO);
+                short vib_delay = getGeneratorValue(generators,
+                        SF2Region.GENERATOR_DELAYVIBLFO);
+                addTimecentValue(performer,
+                        ModelDestination.DESTINATION_LFO2_DELAY, vib_delay);
+                addValue(performer,
+                        ModelDestination.DESTINATION_LFO2_FREQ, vib_freq);
+
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_VIBLFOTOPITCH) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_VIBLFOTOPITCH);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO2;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_MODLFOTOFILTERFC) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOFILTERFC);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_FILTER_FREQ;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_MODLFOTOPITCH) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOPITCH);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_MODLFOTOVOLUME) != 0) {
+                    double fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_MODLFOTOVOLUME);
+                    ModelIdentifier src = ModelSource.SOURCE_LFO1;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_GAIN;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(
+                            new ModelSource(src,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_BIPOLAR),
+                            fvalue, new ModelDestination(dest)));
+                }
+
+                if (layerzone.getShort(SF2Region.GENERATOR_KEYNUM) != -1) {
+                    double val = layerzone.getShort(SF2Region.GENERATOR_KEYNUM)/128.0;
+                    addValue(performer, ModelDestination.DESTINATION_KEYNUMBER, val);
+                }
+
+                if (layerzone.getShort(SF2Region.GENERATOR_VELOCITY) != -1) {
+                    double val = layerzone.getShort(SF2Region.GENERATOR_VELOCITY)
+                                 / 128.0;
+                    addValue(performer, ModelDestination.DESTINATION_VELOCITY, val);
+                }
+
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_INITIALFILTERFC) < 13500) {
+                    short filter_freq = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_INITIALFILTERFC);
+                    short filter_q = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_INITIALFILTERQ);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_FILTER_FREQ, filter_freq);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_FILTER_Q, filter_q);
+                }
+
+                int tune = 100 * getGeneratorValue(generators,
+                        SF2Region.GENERATOR_COARSETUNE);
+                tune += getGeneratorValue(generators,
+                        SF2Region.GENERATOR_FINETUNE);
+                if (tune != 0) {
+                    addValue(performer,
+                            ModelDestination.DESTINATION_PITCH, (short) tune);
+                }
+                if (getGeneratorValue(generators, SF2Region.GENERATOR_PAN) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_PAN);
+                    addValue(performer, ModelDestination.DESTINATION_PAN, val);
+                }
+                if (getGeneratorValue(generators, SF2Region.GENERATOR_INITIALATTENUATION) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_INITIALATTENUATION);
+                    addValue(performer,
+                            ModelDestination.DESTINATION_GAIN, -0.376287f * val);
+                }
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_CHORUSEFFECTSSEND) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_CHORUSEFFECTSSEND);
+                    addValue(performer, ModelDestination.DESTINATION_CHORUS, val);
+                }
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_REVERBEFFECTSSEND) != 0) {
+                    short val = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_REVERBEFFECTSSEND);
+                    addValue(performer, ModelDestination.DESTINATION_REVERB, val);
+                }
+                if (getGeneratorValue(generators,
+                        SF2Region.GENERATOR_SCALETUNING) != 100) {
+                    short fvalue = getGeneratorValue(generators,
+                            SF2Region.GENERATOR_SCALETUNING);
+                    if (fvalue == 0) {
+                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(null, rootkey * 100,
+                                new ModelDestination(dest)));
+                    } else {
+                        ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                        performer.getConnectionBlocks().add(
+                            new ModelConnectionBlock(null, rootkey * (100 - fvalue),
+                                new ModelDestination(dest)));
+                    }
+
+                    ModelIdentifier src = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+                    ModelIdentifier dest = ModelDestination.DESTINATION_PITCH;
+                    performer.getConnectionBlocks().add(
+                        new ModelConnectionBlock(new ModelSource(src),
+                            128 * fvalue, new ModelDestination(dest)));
+
+                }
+
+                performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_NOTEON_VELOCITY,
+                            new ModelTransform() {
+                                public double transform(double value) {
+                                    if (value < 0.5)
+                                        return 1 - value * 2;
+                                    else
+                                        return 0;
+                                }
+                            }),
+                        -2400,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_FILTER_FREQ)));
+
+
+                performer.getConnectionBlocks().add(
+                    new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO2,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_BIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        50, new ModelDestination(
+                            ModelDestination.DESTINATION_PITCH)));
+
+                if (layer.getGlobalRegion() != null) {
+                    for (SF2Modulator modulator
+                            : layer.getGlobalRegion().getModulators()) {
+                        convertModulator(performer, modulator);
+                    }
+                }
+                for (SF2Modulator modulator : layerzone.getModulators())
+                    convertModulator(performer, modulator);
+
+                if (presetglobal != null) {
+                    for (SF2Modulator modulator : presetglobal.getModulators())
+                        convertModulator(performer, modulator);
+                }
+                for (SF2Modulator modulator : presetzone.getModulators())
+                    convertModulator(performer, modulator);
+
+            }
+        }
+        return performers;
+    }
+
+    private void convertModulator(ModelPerformer performer,
+            SF2Modulator modulator) {
+        ModelSource src1 = convertSource(modulator.getSourceOperator());
+        ModelSource src2 = convertSource(modulator.getAmountSourceOperator());
+        if (src1 == null && modulator.getSourceOperator() != 0)
+            return;
+        if (src2 == null && modulator.getAmountSourceOperator() != 0)
+            return;
+        double amount = modulator.getAmount();
+        double[] amountcorrection = new double[1];
+        ModelSource[] extrasrc = new ModelSource[1];
+        amountcorrection[0] = 1;
+        ModelDestination dst = convertDestination(
+                modulator.getDestinationOperator(), amountcorrection, extrasrc);
+        amount *= amountcorrection[0];
+        if (dst == null)
+            return;
+        if (modulator.getTransportOperator() == SF2Modulator.TRANSFORM_ABSOLUTE) {
+            ((ModelStandardTransform)dst.getTransform()).setTransform(
+                    ModelStandardTransform.TRANSFORM_ABSOLUTE);
+        }
+        ModelConnectionBlock conn = new ModelConnectionBlock(src1, src2, amount, dst);
+        if (extrasrc[0] != null)
+            conn.addSource(extrasrc[0]);
+        performer.getConnectionBlocks().add(conn);
+
+    }
+
+    private static ModelSource convertSource(int src) {
+        if (src == 0)
+            return null;
+        ModelIdentifier id = null;
+        int idsrc = src & 0x7F;
+        if ((src & SF2Modulator.SOURCE_MIDI_CONTROL) != 0) {
+            id = new ModelIdentifier("midi_cc", Integer.toString(idsrc));
+        } else {
+            if (idsrc == SF2Modulator.SOURCE_NOTE_ON_VELOCITY)
+                id = ModelSource.SOURCE_NOTEON_VELOCITY;
+            if (idsrc == SF2Modulator.SOURCE_NOTE_ON_KEYNUMBER)
+                id = ModelSource.SOURCE_NOTEON_KEYNUMBER;
+            if (idsrc == SF2Modulator.SOURCE_POLY_PRESSURE)
+                id = ModelSource.SOURCE_MIDI_POLY_PRESSURE;
+            if (idsrc == SF2Modulator.SOURCE_CHANNEL_PRESSURE)
+                id = ModelSource.SOURCE_MIDI_CHANNEL_PRESSURE;
+            if (idsrc == SF2Modulator.SOURCE_PITCH_WHEEL)
+                id = ModelSource.SOURCE_MIDI_PITCH;
+            if (idsrc == SF2Modulator.SOURCE_PITCH_SENSITIVITY)
+                id = new ModelIdentifier("midi_rpn", "0");
+        }
+        if (id == null)
+            return null;
+
+        ModelSource msrc = new ModelSource(id);
+        ModelStandardTransform transform
+                = (ModelStandardTransform) msrc.getTransform();
+
+        if ((SF2Modulator.SOURCE_DIRECTION_MAX_MIN & src) != 0)
+            transform.setDirection(ModelStandardTransform.DIRECTION_MAX2MIN);
+        else
+            transform.setDirection(ModelStandardTransform.DIRECTION_MIN2MAX);
+
+        if ((SF2Modulator.SOURCE_POLARITY_BIPOLAR & src) != 0)
+            transform.setPolarity(ModelStandardTransform.POLARITY_BIPOLAR);
+        else
+            transform.setPolarity(ModelStandardTransform.POLARITY_UNIPOLAR);
+
+        if ((SF2Modulator.SOURCE_TYPE_CONCAVE & src) != 0)
+            transform.setTransform(ModelStandardTransform.TRANSFORM_CONCAVE);
+        if ((SF2Modulator.SOURCE_TYPE_CONVEX & src) != 0)
+            transform.setTransform(ModelStandardTransform.TRANSFORM_CONVEX);
+        if ((SF2Modulator.SOURCE_TYPE_SWITCH & src) != 0)
+            transform.setTransform(ModelStandardTransform.TRANSFORM_SWITCH);
+
+        return msrc;
+    }
+
+    protected static ModelDestination convertDestination(int dst,
+            double[] amountcorrection, ModelSource[] extrasrc) {
+        ModelIdentifier id = null;
+        switch (dst) {
+            case SF2Region.GENERATOR_INITIALFILTERFC:
+                id = ModelDestination.DESTINATION_FILTER_FREQ;
+                break;
+            case SF2Region.GENERATOR_INITIALFILTERQ:
+                id = ModelDestination.DESTINATION_FILTER_Q;
+                break;
+            case SF2Region.GENERATOR_CHORUSEFFECTSSEND:
+                id = ModelDestination.DESTINATION_CHORUS;
+                break;
+            case SF2Region.GENERATOR_REVERBEFFECTSSEND:
+                id = ModelDestination.DESTINATION_REVERB;
+                break;
+            case SF2Region.GENERATOR_PAN:
+                id = ModelDestination.DESTINATION_PAN;
+                break;
+            case SF2Region.GENERATOR_DELAYMODLFO:
+                id = ModelDestination.DESTINATION_LFO1_DELAY;
+                break;
+            case SF2Region.GENERATOR_FREQMODLFO:
+                id = ModelDestination.DESTINATION_LFO1_FREQ;
+                break;
+            case SF2Region.GENERATOR_DELAYVIBLFO:
+                id = ModelDestination.DESTINATION_LFO2_DELAY;
+                break;
+            case SF2Region.GENERATOR_FREQVIBLFO:
+                id = ModelDestination.DESTINATION_LFO2_FREQ;
+                break;
+
+            case SF2Region.GENERATOR_DELAYMODENV:
+                id = ModelDestination.DESTINATION_EG2_DELAY;
+                break;
+            case SF2Region.GENERATOR_ATTACKMODENV:
+                id = ModelDestination.DESTINATION_EG2_ATTACK;
+                break;
+            case SF2Region.GENERATOR_HOLDMODENV:
+                id = ModelDestination.DESTINATION_EG2_HOLD;
+                break;
+            case SF2Region.GENERATOR_DECAYMODENV:
+                id = ModelDestination.DESTINATION_EG2_DECAY;
+                break;
+            case SF2Region.GENERATOR_SUSTAINMODENV:
+                id = ModelDestination.DESTINATION_EG2_SUSTAIN;
+                amountcorrection[0] = -1;
+                break;
+            case SF2Region.GENERATOR_RELEASEMODENV:
+                id = ModelDestination.DESTINATION_EG2_RELEASE;
+                break;
+            case SF2Region.GENERATOR_DELAYVOLENV:
+                id = ModelDestination.DESTINATION_EG1_DELAY;
+                break;
+            case SF2Region.GENERATOR_ATTACKVOLENV:
+                id = ModelDestination.DESTINATION_EG1_ATTACK;
+                break;
+            case SF2Region.GENERATOR_HOLDVOLENV:
+                id = ModelDestination.DESTINATION_EG1_HOLD;
+                break;
+            case SF2Region.GENERATOR_DECAYVOLENV:
+                id = ModelDestination.DESTINATION_EG1_DECAY;
+                break;
+            case SF2Region.GENERATOR_SUSTAINVOLENV:
+                id = ModelDestination.DESTINATION_EG1_SUSTAIN;
+                amountcorrection[0] = -1;
+                break;
+            case SF2Region.GENERATOR_RELEASEVOLENV:
+                id = ModelDestination.DESTINATION_EG1_RELEASE;
+                break;
+            case SF2Region.GENERATOR_KEYNUM:
+                id = ModelDestination.DESTINATION_KEYNUMBER;
+                break;
+            case SF2Region.GENERATOR_VELOCITY:
+                id = ModelDestination.DESTINATION_VELOCITY;
+                break;
+
+            case SF2Region.GENERATOR_COARSETUNE:
+                amountcorrection[0] = 100;
+                id = ModelDestination.DESTINATION_PITCH;
+                break;
+
+            case SF2Region.GENERATOR_FINETUNE:
+                id = ModelDestination.DESTINATION_PITCH;
+                break;
+
+            case SF2Region.GENERATOR_INITIALATTENUATION:
+                id = ModelDestination.DESTINATION_GAIN;
+                amountcorrection[0] = -0.376287f;
+                break;
+
+            case SF2Region.GENERATOR_VIBLFOTOPITCH:
+                id = ModelDestination.DESTINATION_PITCH;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO2,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODLFOTOPITCH:
+                id = ModelDestination.DESTINATION_PITCH;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODLFOTOFILTERFC:
+                id = ModelDestination.DESTINATION_FILTER_FREQ;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODLFOTOVOLUME:
+                id = ModelDestination.DESTINATION_GAIN;
+                amountcorrection[0] = -0.376287f;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODENVTOPITCH:
+                id = ModelDestination.DESTINATION_PITCH;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_EG2,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            case SF2Region.GENERATOR_MODENVTOFILTERFC:
+                id = ModelDestination.DESTINATION_FILTER_FREQ;
+                extrasrc[0] = new ModelSource(
+                        ModelSource.SOURCE_EG2,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR);
+                break;
+
+            default:
+                break;
+        }
+        if (id != null)
+            return new ModelDestination(id);
+        return null;
+    }
+
+    private void addTimecentValue(ModelPerformer performer,
+            ModelIdentifier dest, short value) {
+        double fvalue;
+        if (value == -12000)
+            fvalue = Double.NEGATIVE_INFINITY;
+        else
+            fvalue = value;
+        performer.getConnectionBlocks().add(
+                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
+    }
+
+    private void addValue(ModelPerformer performer,
+            ModelIdentifier dest, short value) {
+        double fvalue = value;
+        performer.getConnectionBlocks().add(
+                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
+    }
+
+    private void addValue(ModelPerformer performer,
+            ModelIdentifier dest, double value) {
+        double fvalue = value;
+        performer.getConnectionBlocks().add(
+                new ModelConnectionBlock(fvalue, new ModelDestination(dest)));
+    }
+
+    private short getGeneratorValue(Map<Integer, Short> generators, int gen) {
+        if (generators.containsKey(gen))
+            return generators.get(gen);
+        return SF2Region.getDefaultValue(gen);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2InstrumentRegion.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2InstrumentRegion.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,43 +1,43 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Soundfont instrument region.
- *
- * @author Karl Helgason
- */
-public class SF2InstrumentRegion extends SF2Region {
-
-    protected SF2Layer layer;
-
-    public SF2Layer getLayer() {
-        return layer;
-    }
-
-    public void setLayer(SF2Layer layer) {
-        this.layer = layer;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont instrument region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2InstrumentRegion extends SF2Region {
+
+    protected SF2Layer layer;
+
+    public SF2Layer getLayer() {
+        return layer;
+    }
+
+    public void setLayer(SF2Layer layer) {
+        this.layer = layer;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Layer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Layer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,78 +1,78 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.sound.midi.SoundbankResource;
-
-/**
- * Soundfont layer.
- *
- * @author Karl Helgason
- */
-public class SF2Layer extends SoundbankResource {
-
-    protected String name = "";
-    protected SF2GlobalRegion globalregion = null;
-    protected List<SF2LayerRegion> regions = new ArrayList<SF2LayerRegion>();
-
-    public SF2Layer(SF2Soundbank soundBank) {
-        super(soundBank, null, null);
-    }
-
-    public SF2Layer() {
-        super(null, null, null);
-    }
-
-    public Object getData() {
-        return null;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public List<SF2LayerRegion> getRegions() {
-        return regions;
-    }
-
-    public SF2GlobalRegion getGlobalRegion() {
-        return globalregion;
-    }
-
-    public void setGlobalZone(SF2GlobalRegion zone) {
-        globalregion = zone;
-    }
-
-    public String toString() {
-        return "Layer: " + name;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sound.midi.SoundbankResource;
+
+/**
+ * Soundfont layer.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Layer extends SoundbankResource {
+
+    protected String name = "";
+    protected SF2GlobalRegion globalregion = null;
+    protected List<SF2LayerRegion> regions = new ArrayList<SF2LayerRegion>();
+
+    public SF2Layer(SF2Soundbank soundBank) {
+        super(soundBank, null, null);
+    }
+
+    public SF2Layer() {
+        super(null, null, null);
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public List<SF2LayerRegion> getRegions() {
+        return regions;
+    }
+
+    public SF2GlobalRegion getGlobalRegion() {
+        return globalregion;
+    }
+
+    public void setGlobalZone(SF2GlobalRegion zone) {
+        globalregion = zone;
+    }
+
+    public String toString() {
+        return "Layer: " + name;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2LayerRegion.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2LayerRegion.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,43 +1,43 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Soundfont layer region.
- *
- * @author Karl Helgason
- */
-public class SF2LayerRegion extends SF2Region {
-
-    protected SF2Sample sample;
-
-    public SF2Sample getSample() {
-        return sample;
-    }
-
-    public void setSample(SF2Sample sample) {
-        this.sample = sample;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont layer region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2LayerRegion extends SF2Region {
+
+    protected SF2Sample sample;
+
+    public SF2Sample getSample() {
+        return sample;
+    }
+
+    public void setSample(SF2Sample sample) {
+        this.sample = sample;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Modulator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Modulator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,97 +1,97 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Soundfont modulator container.
- *
- * @author Karl Helgason
- */
-public class SF2Modulator {
-
-    public final static int SOURCE_NONE = 0;
-    public final static int SOURCE_NOTE_ON_VELOCITY = 2;
-    public final static int SOURCE_NOTE_ON_KEYNUMBER = 3;
-    public final static int SOURCE_POLY_PRESSURE = 10;
-    public final static int SOURCE_CHANNEL_PRESSURE = 13;
-    public final static int SOURCE_PITCH_WHEEL = 14;
-    public final static int SOURCE_PITCH_SENSITIVITY = 16;
-    public final static int SOURCE_MIDI_CONTROL = 128 * 1;
-    public final static int SOURCE_DIRECTION_MIN_MAX = 256 * 0;
-    public final static int SOURCE_DIRECTION_MAX_MIN = 256 * 1;
-    public final static int SOURCE_POLARITY_UNIPOLAR = 512 * 0;
-    public final static int SOURCE_POLARITY_BIPOLAR = 512 * 1;
-    public final static int SOURCE_TYPE_LINEAR = 1024 * 0;
-    public final static int SOURCE_TYPE_CONCAVE = 1024 * 1;
-    public final static int SOURCE_TYPE_CONVEX = 1024 * 2;
-    public final static int SOURCE_TYPE_SWITCH = 1024 * 3;
-    public final static int TRANSFORM_LINEAR = 0;
-    public final static int TRANSFORM_ABSOLUTE = 2;
-    protected int sourceOperator;
-    protected int destinationOperator;
-    protected short amount;
-    protected int amountSourceOperator;
-    protected int transportOperator;
-
-    public short getAmount() {
-        return amount;
-    }
-
-    public void setAmount(short amount) {
-        this.amount = amount;
-    }
-
-    public int getAmountSourceOperator() {
-        return amountSourceOperator;
-    }
-
-    public void setAmountSourceOperator(int amountSourceOperator) {
-        this.amountSourceOperator = amountSourceOperator;
-    }
-
-    public int getTransportOperator() {
-        return transportOperator;
-    }
-
-    public void setTransportOperator(int transportOperator) {
-        this.transportOperator = transportOperator;
-    }
-
-    public int getDestinationOperator() {
-        return destinationOperator;
-    }
-
-    public void setDestinationOperator(int destinationOperator) {
-        this.destinationOperator = destinationOperator;
-    }
-
-    public int getSourceOperator() {
-        return sourceOperator;
-    }
-
-    public void setSourceOperator(int sourceOperator) {
-        this.sourceOperator = sourceOperator;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Soundfont modulator container.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Modulator {
+
+    public final static int SOURCE_NONE = 0;
+    public final static int SOURCE_NOTE_ON_VELOCITY = 2;
+    public final static int SOURCE_NOTE_ON_KEYNUMBER = 3;
+    public final static int SOURCE_POLY_PRESSURE = 10;
+    public final static int SOURCE_CHANNEL_PRESSURE = 13;
+    public final static int SOURCE_PITCH_WHEEL = 14;
+    public final static int SOURCE_PITCH_SENSITIVITY = 16;
+    public final static int SOURCE_MIDI_CONTROL = 128 * 1;
+    public final static int SOURCE_DIRECTION_MIN_MAX = 256 * 0;
+    public final static int SOURCE_DIRECTION_MAX_MIN = 256 * 1;
+    public final static int SOURCE_POLARITY_UNIPOLAR = 512 * 0;
+    public final static int SOURCE_POLARITY_BIPOLAR = 512 * 1;
+    public final static int SOURCE_TYPE_LINEAR = 1024 * 0;
+    public final static int SOURCE_TYPE_CONCAVE = 1024 * 1;
+    public final static int SOURCE_TYPE_CONVEX = 1024 * 2;
+    public final static int SOURCE_TYPE_SWITCH = 1024 * 3;
+    public final static int TRANSFORM_LINEAR = 0;
+    public final static int TRANSFORM_ABSOLUTE = 2;
+    protected int sourceOperator;
+    protected int destinationOperator;
+    protected short amount;
+    protected int amountSourceOperator;
+    protected int transportOperator;
+
+    public short getAmount() {
+        return amount;
+    }
+
+    public void setAmount(short amount) {
+        this.amount = amount;
+    }
+
+    public int getAmountSourceOperator() {
+        return amountSourceOperator;
+    }
+
+    public void setAmountSourceOperator(int amountSourceOperator) {
+        this.amountSourceOperator = amountSourceOperator;
+    }
+
+    public int getTransportOperator() {
+        return transportOperator;
+    }
+
+    public void setTransportOperator(int transportOperator) {
+        this.transportOperator = transportOperator;
+    }
+
+    public int getDestinationOperator() {
+        return destinationOperator;
+    }
+
+    public void setDestinationOperator(int destinationOperator) {
+        this.destinationOperator = destinationOperator;
+    }
+
+    public int getSourceOperator() {
+        return sourceOperator;
+    }
+
+    public void setSourceOperator(int sourceOperator) {
+        this.sourceOperator = sourceOperator;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Region.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Region.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,167 +1,167 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Soundfont general region.
- *
- * @author Karl Helgason
- */
-public class SF2Region {
-
-    public final static int GENERATOR_STARTADDRSOFFSET = 0;
-    public final static int GENERATOR_ENDADDRSOFFSET = 1;
-    public final static int GENERATOR_STARTLOOPADDRSOFFSET = 2;
-    public final static int GENERATOR_ENDLOOPADDRSOFFSET = 3;
-    public final static int GENERATOR_STARTADDRSCOARSEOFFSET = 4;
-    public final static int GENERATOR_MODLFOTOPITCH = 5;
-    public final static int GENERATOR_VIBLFOTOPITCH = 6;
-    public final static int GENERATOR_MODENVTOPITCH = 7;
-    public final static int GENERATOR_INITIALFILTERFC = 8;
-    public final static int GENERATOR_INITIALFILTERQ = 9;
-    public final static int GENERATOR_MODLFOTOFILTERFC = 10;
-    public final static int GENERATOR_MODENVTOFILTERFC = 11;
-    public final static int GENERATOR_ENDADDRSCOARSEOFFSET = 12;
-    public final static int GENERATOR_MODLFOTOVOLUME = 13;
-    public final static int GENERATOR_UNUSED1 = 14;
-    public final static int GENERATOR_CHORUSEFFECTSSEND = 15;
-    public final static int GENERATOR_REVERBEFFECTSSEND = 16;
-    public final static int GENERATOR_PAN = 17;
-    public final static int GENERATOR_UNUSED2 = 18;
-    public final static int GENERATOR_UNUSED3 = 19;
-    public final static int GENERATOR_UNUSED4 = 20;
-    public final static int GENERATOR_DELAYMODLFO = 21;
-    public final static int GENERATOR_FREQMODLFO = 22;
-    public final static int GENERATOR_DELAYVIBLFO = 23;
-    public final static int GENERATOR_FREQVIBLFO = 24;
-    public final static int GENERATOR_DELAYMODENV = 25;
-    public final static int GENERATOR_ATTACKMODENV = 26;
-    public final static int GENERATOR_HOLDMODENV = 27;
-    public final static int GENERATOR_DECAYMODENV = 28;
-    public final static int GENERATOR_SUSTAINMODENV = 29;
-    public final static int GENERATOR_RELEASEMODENV = 30;
-    public final static int GENERATOR_KEYNUMTOMODENVHOLD = 31;
-    public final static int GENERATOR_KEYNUMTOMODENVDECAY = 32;
-    public final static int GENERATOR_DELAYVOLENV = 33;
-    public final static int GENERATOR_ATTACKVOLENV = 34;
-    public final static int GENERATOR_HOLDVOLENV = 35;
-    public final static int GENERATOR_DECAYVOLENV = 36;
-    public final static int GENERATOR_SUSTAINVOLENV = 37;
-    public final static int GENERATOR_RELEASEVOLENV = 38;
-    public final static int GENERATOR_KEYNUMTOVOLENVHOLD = 39;
-    public final static int GENERATOR_KEYNUMTOVOLENVDECAY = 40;
-    public final static int GENERATOR_INSTRUMENT = 41;
-    public final static int GENERATOR_RESERVED1 = 42;
-    public final static int GENERATOR_KEYRANGE = 43;
-    public final static int GENERATOR_VELRANGE = 44;
-    public final static int GENERATOR_STARTLOOPADDRSCOARSEOFFSET = 45;
-    public final static int GENERATOR_KEYNUM = 46;
-    public final static int GENERATOR_VELOCITY = 47;
-    public final static int GENERATOR_INITIALATTENUATION = 48;
-    public final static int GENERATOR_RESERVED2 = 49;
-    public final static int GENERATOR_ENDLOOPADDRSCOARSEOFFSET = 50;
-    public final static int GENERATOR_COARSETUNE = 51;
-    public final static int GENERATOR_FINETUNE = 52;
-    public final static int GENERATOR_SAMPLEID = 53;
-    public final static int GENERATOR_SAMPLEMODES = 54;
-    public final static int GENERATOR_RESERVED3 = 55;
-    public final static int GENERATOR_SCALETUNING = 56;
-    public final static int GENERATOR_EXCLUSIVECLASS = 57;
-    public final static int GENERATOR_OVERRIDINGROOTKEY = 58;
-    public final static int GENERATOR_UNUSED5 = 59;
-    public final static int GENERATOR_ENDOPR = 60;
-    protected Map<Integer, Short> generators = new HashMap<Integer, Short>();
-    protected List<SF2Modulator> modulators = new ArrayList<SF2Modulator>();
-
-    public Map<Integer, Short> getGenerators() {
-        return generators;
-    }
-
-    public boolean contains(int generator) {
-        return generators.containsKey(generator);
-    }
-
-    static public short getDefaultValue(int generator) {
-        if (generator == 8) return (short)13500;
-        if (generator == 21) return (short)-12000;
-        if (generator == 23) return (short)-12000;
-        if (generator == 25) return (short)-12000;
-        if (generator == 26) return (short)-12000;
-        if (generator == 27) return (short)-12000;
-        if (generator == 28) return (short)-12000;
-        if (generator == 30) return (short)-12000;
-        if (generator == 33) return (short)-12000;
-        if (generator == 34) return (short)-12000;
-        if (generator == 35) return (short)-12000;
-        if (generator == 36) return (short)-12000;
-        if (generator == 38) return (short)-12000;
-        if (generator == 43) return (short)0x7F00;
-        if (generator == 44) return (short)0x7F00;
-        if (generator == 46) return (short)-1;
-        if (generator == 47) return (short)-1;
-        if (generator == 56) return (short)100;
-        if (generator == 58) return (short)-1;
-        return 0;
-    }
-
-    public short getShort(int generator) {
-        if (!contains(generator))
-            return getDefaultValue(generator);
-        return generators.get(generator);
-    }
-
-    public void putShort(int generator, short value) {
-        generators.put(generator, value);
-    }
-
-    public byte[] getBytes(int generator) {
-        int val = getInteger(generator);
-        byte[] bytes = new byte[2];
-        bytes[0] = (byte) (0xFF & val);
-        bytes[1] = (byte) ((0xFF00 & val) >> 8);
-        return bytes;
-    }
-
-    public void putBytes(int generator, byte[] bytes) {
-        generators.put(generator, (short) (bytes[0] + (bytes[1] << 8)));
-    }
-
-    public int getInteger(int generator) {
-        return 0xFFFF & getShort(generator);
-    }
-
-    public void putInteger(int generator, int value) {
-        generators.put(generator, (short) value);
-    }
-
-    public List<SF2Modulator> getModulators() {
-        return modulators;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Soundfont general region.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Region {
+
+    public final static int GENERATOR_STARTADDRSOFFSET = 0;
+    public final static int GENERATOR_ENDADDRSOFFSET = 1;
+    public final static int GENERATOR_STARTLOOPADDRSOFFSET = 2;
+    public final static int GENERATOR_ENDLOOPADDRSOFFSET = 3;
+    public final static int GENERATOR_STARTADDRSCOARSEOFFSET = 4;
+    public final static int GENERATOR_MODLFOTOPITCH = 5;
+    public final static int GENERATOR_VIBLFOTOPITCH = 6;
+    public final static int GENERATOR_MODENVTOPITCH = 7;
+    public final static int GENERATOR_INITIALFILTERFC = 8;
+    public final static int GENERATOR_INITIALFILTERQ = 9;
+    public final static int GENERATOR_MODLFOTOFILTERFC = 10;
+    public final static int GENERATOR_MODENVTOFILTERFC = 11;
+    public final static int GENERATOR_ENDADDRSCOARSEOFFSET = 12;
+    public final static int GENERATOR_MODLFOTOVOLUME = 13;
+    public final static int GENERATOR_UNUSED1 = 14;
+    public final static int GENERATOR_CHORUSEFFECTSSEND = 15;
+    public final static int GENERATOR_REVERBEFFECTSSEND = 16;
+    public final static int GENERATOR_PAN = 17;
+    public final static int GENERATOR_UNUSED2 = 18;
+    public final static int GENERATOR_UNUSED3 = 19;
+    public final static int GENERATOR_UNUSED4 = 20;
+    public final static int GENERATOR_DELAYMODLFO = 21;
+    public final static int GENERATOR_FREQMODLFO = 22;
+    public final static int GENERATOR_DELAYVIBLFO = 23;
+    public final static int GENERATOR_FREQVIBLFO = 24;
+    public final static int GENERATOR_DELAYMODENV = 25;
+    public final static int GENERATOR_ATTACKMODENV = 26;
+    public final static int GENERATOR_HOLDMODENV = 27;
+    public final static int GENERATOR_DECAYMODENV = 28;
+    public final static int GENERATOR_SUSTAINMODENV = 29;
+    public final static int GENERATOR_RELEASEMODENV = 30;
+    public final static int GENERATOR_KEYNUMTOMODENVHOLD = 31;
+    public final static int GENERATOR_KEYNUMTOMODENVDECAY = 32;
+    public final static int GENERATOR_DELAYVOLENV = 33;
+    public final static int GENERATOR_ATTACKVOLENV = 34;
+    public final static int GENERATOR_HOLDVOLENV = 35;
+    public final static int GENERATOR_DECAYVOLENV = 36;
+    public final static int GENERATOR_SUSTAINVOLENV = 37;
+    public final static int GENERATOR_RELEASEVOLENV = 38;
+    public final static int GENERATOR_KEYNUMTOVOLENVHOLD = 39;
+    public final static int GENERATOR_KEYNUMTOVOLENVDECAY = 40;
+    public final static int GENERATOR_INSTRUMENT = 41;
+    public final static int GENERATOR_RESERVED1 = 42;
+    public final static int GENERATOR_KEYRANGE = 43;
+    public final static int GENERATOR_VELRANGE = 44;
+    public final static int GENERATOR_STARTLOOPADDRSCOARSEOFFSET = 45;
+    public final static int GENERATOR_KEYNUM = 46;
+    public final static int GENERATOR_VELOCITY = 47;
+    public final static int GENERATOR_INITIALATTENUATION = 48;
+    public final static int GENERATOR_RESERVED2 = 49;
+    public final static int GENERATOR_ENDLOOPADDRSCOARSEOFFSET = 50;
+    public final static int GENERATOR_COARSETUNE = 51;
+    public final static int GENERATOR_FINETUNE = 52;
+    public final static int GENERATOR_SAMPLEID = 53;
+    public final static int GENERATOR_SAMPLEMODES = 54;
+    public final static int GENERATOR_RESERVED3 = 55;
+    public final static int GENERATOR_SCALETUNING = 56;
+    public final static int GENERATOR_EXCLUSIVECLASS = 57;
+    public final static int GENERATOR_OVERRIDINGROOTKEY = 58;
+    public final static int GENERATOR_UNUSED5 = 59;
+    public final static int GENERATOR_ENDOPR = 60;
+    protected Map<Integer, Short> generators = new HashMap<Integer, Short>();
+    protected List<SF2Modulator> modulators = new ArrayList<SF2Modulator>();
+
+    public Map<Integer, Short> getGenerators() {
+        return generators;
+    }
+
+    public boolean contains(int generator) {
+        return generators.containsKey(generator);
+    }
+
+    static public short getDefaultValue(int generator) {
+        if (generator == 8) return (short)13500;
+        if (generator == 21) return (short)-12000;
+        if (generator == 23) return (short)-12000;
+        if (generator == 25) return (short)-12000;
+        if (generator == 26) return (short)-12000;
+        if (generator == 27) return (short)-12000;
+        if (generator == 28) return (short)-12000;
+        if (generator == 30) return (short)-12000;
+        if (generator == 33) return (short)-12000;
+        if (generator == 34) return (short)-12000;
+        if (generator == 35) return (short)-12000;
+        if (generator == 36) return (short)-12000;
+        if (generator == 38) return (short)-12000;
+        if (generator == 43) return (short)0x7F00;
+        if (generator == 44) return (short)0x7F00;
+        if (generator == 46) return (short)-1;
+        if (generator == 47) return (short)-1;
+        if (generator == 56) return (short)100;
+        if (generator == 58) return (short)-1;
+        return 0;
+    }
+
+    public short getShort(int generator) {
+        if (!contains(generator))
+            return getDefaultValue(generator);
+        return generators.get(generator);
+    }
+
+    public void putShort(int generator, short value) {
+        generators.put(generator, value);
+    }
+
+    public byte[] getBytes(int generator) {
+        int val = getInteger(generator);
+        byte[] bytes = new byte[2];
+        bytes[0] = (byte) (0xFF & val);
+        bytes[1] = (byte) ((0xFF00 & val) >> 8);
+        return bytes;
+    }
+
+    public void putBytes(int generator, byte[] bytes) {
+        generators.put(generator, (short) (bytes[0] + (bytes[1] << 8)));
+    }
+
+    public int getInteger(int generator) {
+        return 0xFFFF & getShort(generator);
+    }
+
+    public void putInteger(int generator, int value) {
+        generators.put(generator, (short) value);
+    }
+
+    public List<SF2Modulator> getModulators() {
+        return modulators;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Sample.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Sample.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,216 +1,216 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.InputStream;
-
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.SoundbankResource;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-
-/**
- * Soundfont sample storage.
- *
- * @author Karl Helgason
- */
-public class SF2Sample extends SoundbankResource {
-
-    protected String name = "";
-    protected long startLoop = 0;
-    protected long endLoop = 0;
-    protected long sampleRate = 44100;
-    protected int originalPitch = 60;
-    protected byte pitchCorrection = 0;
-    protected int sampleLink = 0;
-    protected int sampleType = 0;
-    protected ModelByteBuffer data;
-    protected ModelByteBuffer data24;
-
-    public SF2Sample(Soundbank soundBank) {
-        super(soundBank, null, AudioInputStream.class);
-    }
-
-    public SF2Sample() {
-        super(null, null, AudioInputStream.class);
-    }
-
-    public Object getData() {
-
-        AudioFormat format = getFormat();
-        /*
-        if (sampleFile != null) {
-            FileInputStream fis;
-            try {
-                fis = new FileInputStream(sampleFile);
-                RIFFReader riff = new RIFFReader(fis);
-                if (!riff.getFormat().equals("RIFF")) {
-                    throw new RIFFInvalidDataException(
-                        "Input stream is not a valid RIFF stream!");
-                }
-                if (!riff.getType().equals("sfbk")) {
-                    throw new RIFFInvalidDataException(
-                        "Input stream is not a valid SoundFont!");
-                }
-                while (riff.hasNextChunk()) {
-                    RIFFReader chunk = riff.nextChunk();
-                    if (chunk.getFormat().equals("LIST")) {
-                        if (chunk.getType().equals("sdta")) {
-                            while(chunk.hasNextChunk()) {
-                                RIFFReader chunkchunk = chunk.nextChunk();
-                                if(chunkchunk.getFormat().equals("smpl")) {
-                                    chunkchunk.skip(sampleOffset);
-                                    return new AudioInputStream(chunkchunk,
-                                            format, sampleLen);
-                                }
-                            }
-                        }
-                    }
-                }
-                return null;
-            } catch (Exception e) {
-                return new Throwable(e.toString());
-            }
-        }
-        */
-        InputStream is = data.getInputStream();
-        if (is == null)
-            return null;
-        return new AudioInputStream(is, format, data.capacity());
-    }
-
-    public ModelByteBuffer getDataBuffer() {
-        return data;
-    }
-
-    public ModelByteBuffer getData24Buffer() {
-        return data24;
-    }
-
-    public AudioFormat getFormat() {
-        return new AudioFormat(sampleRate, 16, 1, true, false);
-    }
-
-    public void setData(ModelByteBuffer data) {
-        this.data = data;
-    }
-
-    public void setData(byte[] data) {
-        this.data = new ModelByteBuffer(data);
-    }
-
-    public void setData(byte[] data, int offset, int length) {
-        this.data = new ModelByteBuffer(data, offset, length);
-    }
-
-    public void setData24(ModelByteBuffer data24) {
-        this.data24 = data24;
-    }
-
-    public void setData24(byte[] data24) {
-        this.data24 = new ModelByteBuffer(data24);
-    }
-
-    public void setData24(byte[] data24, int offset, int length) {
-        this.data24 = new ModelByteBuffer(data24, offset, length);
-    }
-
-    /*
-    public void setData(File file, int offset, int length) {
-        this.data = null;
-        this.sampleFile = file;
-        this.sampleOffset = offset;
-        this.sampleLen = length;
-    }
-    */
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public long getEndLoop() {
-        return endLoop;
-    }
-
-    public void setEndLoop(long endLoop) {
-        this.endLoop = endLoop;
-    }
-
-    public int getOriginalPitch() {
-        return originalPitch;
-    }
-
-    public void setOriginalPitch(int originalPitch) {
-        this.originalPitch = originalPitch;
-    }
-
-    public byte getPitchCorrection() {
-        return pitchCorrection;
-    }
-
-    public void setPitchCorrection(byte pitchCorrection) {
-        this.pitchCorrection = pitchCorrection;
-    }
-
-    public int getSampleLink() {
-        return sampleLink;
-    }
-
-    public void setSampleLink(int sampleLink) {
-        this.sampleLink = sampleLink;
-    }
-
-    public long getSampleRate() {
-        return sampleRate;
-    }
-
-    public void setSampleRate(long sampleRate) {
-        this.sampleRate = sampleRate;
-    }
-
-    public int getSampleType() {
-        return sampleType;
-    }
-
-    public void setSampleType(int sampleType) {
-        this.sampleType = sampleType;
-    }
-
-    public long getStartLoop() {
-        return startLoop;
-    }
-
-    public void setStartLoop(long startLoop) {
-        this.startLoop = startLoop;
-    }
-
-    public String toString() {
-        return "Sample: " + name;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.InputStream;
+
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * Soundfont sample storage.
+ *
+ * @author Karl Helgason
+ */
+public class SF2Sample extends SoundbankResource {
+
+    protected String name = "";
+    protected long startLoop = 0;
+    protected long endLoop = 0;
+    protected long sampleRate = 44100;
+    protected int originalPitch = 60;
+    protected byte pitchCorrection = 0;
+    protected int sampleLink = 0;
+    protected int sampleType = 0;
+    protected ModelByteBuffer data;
+    protected ModelByteBuffer data24;
+
+    public SF2Sample(Soundbank soundBank) {
+        super(soundBank, null, AudioInputStream.class);
+    }
+
+    public SF2Sample() {
+        super(null, null, AudioInputStream.class);
+    }
+
+    public Object getData() {
+
+        AudioFormat format = getFormat();
+        /*
+        if (sampleFile != null) {
+            FileInputStream fis;
+            try {
+                fis = new FileInputStream(sampleFile);
+                RIFFReader riff = new RIFFReader(fis);
+                if (!riff.getFormat().equals("RIFF")) {
+                    throw new RIFFInvalidDataException(
+                        "Input stream is not a valid RIFF stream!");
+                }
+                if (!riff.getType().equals("sfbk")) {
+                    throw new RIFFInvalidDataException(
+                        "Input stream is not a valid SoundFont!");
+                }
+                while (riff.hasNextChunk()) {
+                    RIFFReader chunk = riff.nextChunk();
+                    if (chunk.getFormat().equals("LIST")) {
+                        if (chunk.getType().equals("sdta")) {
+                            while(chunk.hasNextChunk()) {
+                                RIFFReader chunkchunk = chunk.nextChunk();
+                                if(chunkchunk.getFormat().equals("smpl")) {
+                                    chunkchunk.skip(sampleOffset);
+                                    return new AudioInputStream(chunkchunk,
+                                            format, sampleLen);
+                                }
+                            }
+                        }
+                    }
+                }
+                return null;
+            } catch (Exception e) {
+                return new Throwable(e.toString());
+            }
+        }
+        */
+        InputStream is = data.getInputStream();
+        if (is == null)
+            return null;
+        return new AudioInputStream(is, format, data.capacity());
+    }
+
+    public ModelByteBuffer getDataBuffer() {
+        return data;
+    }
+
+    public ModelByteBuffer getData24Buffer() {
+        return data24;
+    }
+
+    public AudioFormat getFormat() {
+        return new AudioFormat(sampleRate, 16, 1, true, false);
+    }
+
+    public void setData(ModelByteBuffer data) {
+        this.data = data;
+    }
+
+    public void setData(byte[] data) {
+        this.data = new ModelByteBuffer(data);
+    }
+
+    public void setData(byte[] data, int offset, int length) {
+        this.data = new ModelByteBuffer(data, offset, length);
+    }
+
+    public void setData24(ModelByteBuffer data24) {
+        this.data24 = data24;
+    }
+
+    public void setData24(byte[] data24) {
+        this.data24 = new ModelByteBuffer(data24);
+    }
+
+    public void setData24(byte[] data24, int offset, int length) {
+        this.data24 = new ModelByteBuffer(data24, offset, length);
+    }
+
+    /*
+    public void setData(File file, int offset, int length) {
+        this.data = null;
+        this.sampleFile = file;
+        this.sampleOffset = offset;
+        this.sampleLen = length;
+    }
+    */
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public long getEndLoop() {
+        return endLoop;
+    }
+
+    public void setEndLoop(long endLoop) {
+        this.endLoop = endLoop;
+    }
+
+    public int getOriginalPitch() {
+        return originalPitch;
+    }
+
+    public void setOriginalPitch(int originalPitch) {
+        this.originalPitch = originalPitch;
+    }
+
+    public byte getPitchCorrection() {
+        return pitchCorrection;
+    }
+
+    public void setPitchCorrection(byte pitchCorrection) {
+        this.pitchCorrection = pitchCorrection;
+    }
+
+    public int getSampleLink() {
+        return sampleLink;
+    }
+
+    public void setSampleLink(int sampleLink) {
+        this.sampleLink = sampleLink;
+    }
+
+    public long getSampleRate() {
+        return sampleRate;
+    }
+
+    public void setSampleRate(long sampleRate) {
+        this.sampleRate = sampleRate;
+    }
+
+    public int getSampleType() {
+        return sampleType;
+    }
+
+    public void setSampleType(int sampleType) {
+        this.sampleType = sampleType;
+    }
+
+    public long getStartLoop() {
+        return startLoop;
+    }
+
+    public void setStartLoop(long startLoop) {
+        this.startLoop = startLoop;
+    }
+
+    public String toString() {
+        return "Sample: " + name;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2Soundbank.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,973 +1,973 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.sound.midi.Instrument;
-import javax.sound.midi.Patch;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.SoundbankResource;
-
-/**
- * A SoundFont 2.04 soundbank reader.
- *
- * Based on SoundFont 2.04 specification from:
- * <p>  http://developer.creative.com <br>
- *      http://www.soundfont.com/ ;
- *
- * @author Karl Helgason
- */
-public class SF2Soundbank implements Soundbank {
-
-    // version of the Sound Font RIFF file
-    protected int major = 2;
-    protected int minor = 1;
-    // target Sound Engine
-    protected String targetEngine = "EMU8000";
-    // Sound Font Bank Name
-    protected String name = "untitled";
-    // Sound ROM Name
-    protected String romName = null;
-    // Sound ROM Version
-    protected int romVersionMajor = -1;
-    protected int romVersionMinor = -1;
-    // Date of Creation of the Bank
-    protected String creationDate = null;
-    // Sound Designers and Engineers for the Bank
-    protected String engineers = null;
-    // Product for which the Bank was intended
-    protected String product = null;
-    // Copyright message
-    protected String copyright = null;
-    // Comments
-    protected String comments = null;
-    // The SoundFont tools used to create and alter the bank
-    protected String tools = null;
-    // The Sample Data loaded from the SoundFont
-    private ModelByteBuffer sampleData = null;
-    private ModelByteBuffer sampleData24 = null;
-    private File sampleFile = null;
-    private boolean largeFormat = false;
-    private List<SF2Instrument> instruments = new ArrayList<SF2Instrument>();
-    private List<SF2Layer> layers = new ArrayList<SF2Layer>();
-    private List<SF2Sample> samples = new ArrayList<SF2Sample>();
-
-    public SF2Soundbank() {
-    }
-
-    public SF2Soundbank(URL url) throws IOException {
-
-        InputStream is = url.openStream();
-        try {
-            readSoundbank(is);
-        } finally {
-            is.close();
-        }
-    }
-
-    public SF2Soundbank(File file) throws IOException {
-        largeFormat = true;
-        sampleFile = file;
-        InputStream is = new FileInputStream(file);
-        try {
-            readSoundbank(is);
-        } finally {
-            is.close();
-        }
-    }
-
-    public SF2Soundbank(InputStream inputstream) throws IOException {
-        readSoundbank(inputstream);
-    }
-
-    private void readSoundbank(InputStream inputstream) throws IOException {
-        RIFFReader riff = new RIFFReader(inputstream);
-        if (!riff.getFormat().equals("RIFF")) {
-            throw new RIFFInvalidFormatException(
-                    "Input stream is not a valid RIFF stream!");
-        }
-        if (!riff.getType().equals("sfbk")) {
-            throw new RIFFInvalidFormatException(
-                    "Input stream is not a valid SoundFont!");
-        }
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            if (chunk.getFormat().equals("LIST")) {
-                if (chunk.getType().equals("INFO"))
-                    readInfoChunk(chunk);
-                if (chunk.getType().equals("sdta"))
-                    readSdtaChunk(chunk);
-                if (chunk.getType().equals("pdta"))
-                    readPdtaChunk(chunk);
-            }
-        }
-    }
-
-    private void readInfoChunk(RIFFReader riff) throws IOException {
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("ifil")) {
-                major = chunk.readUnsignedShort();
-                minor = chunk.readUnsignedShort();
-            } else if (format.equals("isng")) {
-                this.targetEngine = chunk.readString(chunk.available());
-            } else if (format.equals("INAM")) {
-                this.name = chunk.readString(chunk.available());
-            } else if (format.equals("irom")) {
-                this.romName = chunk.readString(chunk.available());
-            } else if (format.equals("iver")) {
-                romVersionMajor = chunk.readUnsignedShort();
-                romVersionMinor = chunk.readUnsignedShort();
-            } else if (format.equals("ICRD")) {
-                this.creationDate = chunk.readString(chunk.available());
-            } else if (format.equals("IENG")) {
-                this.engineers = chunk.readString(chunk.available());
-            } else if (format.equals("IPRD")) {
-                this.product = chunk.readString(chunk.available());
-            } else if (format.equals("ICOP")) {
-                this.copyright = chunk.readString(chunk.available());
-            } else if (format.equals("ICMT")) {
-                this.comments = chunk.readString(chunk.available());
-            } else if (format.equals("ISFT")) {
-                this.tools = chunk.readString(chunk.available());
-            }
-
-        }
-    }
-
-    private void readSdtaChunk(RIFFReader riff) throws IOException {
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            if (chunk.getFormat().equals("smpl")) {
-                if (!largeFormat) {
-                    byte[] sampleData = new byte[chunk.available()];
-
-                    int read = 0;
-                    int avail = chunk.available();
-                    while (read != avail) {
-                        if (avail - read > 65536) {
-                            chunk.read(sampleData, read, 65536);
-                            read += 65536;
-                        } else {
-                            chunk.read(sampleData, read, avail - read);
-                            read = avail;
-                        }
-
-                    }
-                    this.sampleData = new ModelByteBuffer(sampleData);
-                    //chunk.read(sampleData);
-                } else {
-                    this.sampleData = new ModelByteBuffer(sampleFile,
-                            chunk.getFilePointer(), chunk.available());
-                }
-            }
-            if (chunk.getFormat().equals("sm24")) {
-                if (!largeFormat) {
-                    byte[] sampleData24 = new byte[chunk.available()];
-                    //chunk.read(sampleData24);
-
-                    int read = 0;
-                    int avail = chunk.available();
-                    while (read != avail) {
-                        if (avail - read > 65536) {
-                            chunk.read(sampleData24, read, 65536);
-                            read += 65536;
-                        } else {
-                            chunk.read(sampleData24, read, avail - read);
-                            read = avail;
-                        }
-
-                    }
-                    this.sampleData24 = new ModelByteBuffer(sampleData24);
-                } else {
-                    this.sampleData24 = new ModelByteBuffer(sampleFile,
-                            chunk.getFilePointer(), chunk.available());
-                }
-
-            }
-        }
-    }
-
-    private void readPdtaChunk(RIFFReader riff) throws IOException {
-
-        List<SF2Instrument> presets = new ArrayList<SF2Instrument>();
-        List<Integer> presets_bagNdx = new ArrayList<Integer>();
-        List<SF2InstrumentRegion> presets_splits_gen
-                = new ArrayList<SF2InstrumentRegion>();
-        List<SF2InstrumentRegion> presets_splits_mod
-                = new ArrayList<SF2InstrumentRegion>();
-
-        List<SF2Layer> instruments = new ArrayList<SF2Layer>();
-        List<Integer> instruments_bagNdx = new ArrayList<Integer>();
-        List<SF2LayerRegion> instruments_splits_gen
-                = new ArrayList<SF2LayerRegion>();
-        List<SF2LayerRegion> instruments_splits_mod
-                = new ArrayList<SF2LayerRegion>();
-
-        while (riff.hasNextChunk()) {
-            RIFFReader chunk = riff.nextChunk();
-            String format = chunk.getFormat();
-            if (format.equals("phdr")) {
-                // Preset Header / Instrument
-                if (chunk.available() % 38 != 0)
-                    throw new RIFFInvalidDataException();
-                int count = chunk.available() / 38;
-                for (int i = 0; i < count; i++) {
-                    SF2Instrument preset = new SF2Instrument(this);
-                    preset.name = chunk.readString(20);
-                    preset.preset = chunk.readUnsignedShort();
-                    preset.bank = chunk.readUnsignedShort();
-                    presets_bagNdx.add(chunk.readUnsignedShort());
-                    preset.library = chunk.readUnsignedInt();
-                    preset.genre = chunk.readUnsignedInt();
-                    preset.morphology = chunk.readUnsignedInt();
-                    presets.add(preset);
-                    if (i != count - 1)
-                        this.instruments.add(preset);
-                }
-            } else if (format.equals("pbag")) {
-                // Preset Zones / Instruments splits
-                if (chunk.available() % 4 != 0)
-                    throw new RIFFInvalidDataException();
-                int count = chunk.available() / 4;
-
-                // Skip first record
-                {
-                    int gencount = chunk.readUnsignedShort();
-                    int modcount = chunk.readUnsignedShort();
-                    while (presets_splits_gen.size() < gencount)
-                        presets_splits_gen.add(null);
-                    while (presets_splits_mod.size() < modcount)
-                        presets_splits_mod.add(null);
-                    count--;
-                }
-
-                int offset = presets_bagNdx.get(0);
-                // Offset should be 0 (but just case)
-                for (int i = 0; i < offset; i++) {
-                    if (count == 0)
-                        throw new RIFFInvalidDataException();
-                    int gencount = chunk.readUnsignedShort();
-                    int modcount = chunk.readUnsignedShort();
-                    while (presets_splits_gen.size() < gencount)
-                        presets_splits_gen.add(null);
-                    while (presets_splits_mod.size() < modcount)
-                        presets_splits_mod.add(null);
-                    count--;
-                }
-
-                for (int i = 0; i < presets_bagNdx.size() - 1; i++) {
-                    int zone_count = presets_bagNdx.get(i + 1)
-                                     - presets_bagNdx.get(i);
-                    SF2Instrument preset = presets.get(i);
-                    for (int ii = 0; ii < zone_count; ii++) {
-                        if (count == 0)
-                            throw new RIFFInvalidDataException();
-                        int gencount = chunk.readUnsignedShort();
-                        int modcount = chunk.readUnsignedShort();
-                        SF2InstrumentRegion split = new SF2InstrumentRegion();
-                        preset.regions.add(split);
-                        while (presets_splits_gen.size() < gencount)
-                            presets_splits_gen.add(split);
-                        while (presets_splits_mod.size() < modcount)
-                            presets_splits_mod.add(split);
-                        count--;
-                    }
-                }
-            } else if (format.equals("pmod")) {
-                // Preset Modulators / Split Modulators
-                for (int i = 0; i < presets_splits_mod.size(); i++) {
-                    SF2Modulator modulator = new SF2Modulator();
-                    modulator.sourceOperator = chunk.readUnsignedShort();
-                    modulator.destinationOperator = chunk.readUnsignedShort();
-                    modulator.amount = chunk.readShort();
-                    modulator.amountSourceOperator = chunk.readUnsignedShort();
-                    modulator.transportOperator = chunk.readUnsignedShort();
-                    SF2InstrumentRegion split = presets_splits_mod.get(i);
-                    if (split != null)
-                        split.modulators.add(modulator);
-                }
-            } else if (format.equals("pgen")) {
-                // Preset Generators / Split Generators
-                for (int i = 0; i < presets_splits_gen.size(); i++) {
-                    int operator = chunk.readUnsignedShort();
-                    short amount = chunk.readShort();
-                    SF2InstrumentRegion split = presets_splits_gen.get(i);
-                    if (split != null)
-                        split.generators.put(operator, amount);
-                }
-            } else if (format.equals("inst")) {
-                // Instrument Header / Layers
-                if (chunk.available() % 22 != 0)
-                    throw new RIFFInvalidDataException();
-                int count = chunk.available() / 22;
-                for (int i = 0; i < count; i++) {
-                    SF2Layer layer = new SF2Layer(this);
-                    layer.name = chunk.readString(20);
-                    instruments_bagNdx.add(chunk.readUnsignedShort());
-                    instruments.add(layer);
-                    if (i != count - 1)
-                        this.layers.add(layer);
-                }
-            } else if (format.equals("ibag")) {
-                // Instrument Zones / Layer splits
-                if (chunk.available() % 4 != 0)
-                    throw new RIFFInvalidDataException();
-                int count = chunk.available() / 4;
-
-                // Skip first record
-                {
-                    int gencount = chunk.readUnsignedShort();
-                    int modcount = chunk.readUnsignedShort();
-                    while (instruments_splits_gen.size() < gencount)
-                        instruments_splits_gen.add(null);
-                    while (instruments_splits_mod.size() < modcount)
-                        instruments_splits_mod.add(null);
-                    count--;
-                }
-
-                int offset = instruments_bagNdx.get(0);
-                // Offset should be 0 (but just case)
-                for (int i = 0; i < offset; i++) {
-                    if (count == 0)
-                        throw new RIFFInvalidDataException();
-                    int gencount = chunk.readUnsignedShort();
-                    int modcount = chunk.readUnsignedShort();
-                    while (instruments_splits_gen.size() < gencount)
-                        instruments_splits_gen.add(null);
-                    while (instruments_splits_mod.size() < modcount)
-                        instruments_splits_mod.add(null);
-                    count--;
-                }
-
-                for (int i = 0; i < instruments_bagNdx.size() - 1; i++) {
-                    int zone_count = instruments_bagNdx.get(i + 1) - instruments_bagNdx.get(i);
-                    SF2Layer layer = layers.get(i);
-                    for (int ii = 0; ii < zone_count; ii++) {
-                        if (count == 0)
-                            throw new RIFFInvalidDataException();
-                        int gencount = chunk.readUnsignedShort();
-                        int modcount = chunk.readUnsignedShort();
-                        SF2LayerRegion split = new SF2LayerRegion();
-                        layer.regions.add(split);
-                        while (instruments_splits_gen.size() < gencount)
-                            instruments_splits_gen.add(split);
-                        while (instruments_splits_mod.size() < modcount)
-                            instruments_splits_mod.add(split);
-                        count--;
-                    }
-                }
-
-            } else if (format.equals("imod")) {
-                // Instrument Modulators / Split Modulators
-                for (int i = 0; i < instruments_splits_mod.size(); i++) {
-                    SF2Modulator modulator = new SF2Modulator();
-                    modulator.sourceOperator = chunk.readUnsignedShort();
-                    modulator.destinationOperator = chunk.readUnsignedShort();
-                    modulator.amount = chunk.readShort();
-                    modulator.amountSourceOperator = chunk.readUnsignedShort();
-                    modulator.transportOperator = chunk.readUnsignedShort();
-                    SF2LayerRegion split = instruments_splits_gen.get(i);
-                    if (split != null)
-                        split.modulators.add(modulator);
-                }
-            } else if (format.equals("igen")) {
-                // Instrument Generators / Split Generators
-                for (int i = 0; i < instruments_splits_gen.size(); i++) {
-                    int operator = chunk.readUnsignedShort();
-                    short amount = chunk.readShort();
-                    SF2LayerRegion split = instruments_splits_gen.get(i);
-                    if (split != null)
-                        split.generators.put(operator, amount);
-                }
-            } else if (format.equals("shdr")) {
-                // Sample Headers
-                if (chunk.available() % 46 != 0)
-                    throw new RIFFInvalidDataException();
-                int count = chunk.available() / 46;
-                for (int i = 0; i < count; i++) {
-                    SF2Sample sample = new SF2Sample(this);
-                    sample.name = chunk.readString(20);
-                    long start = chunk.readUnsignedInt();
-                    long end = chunk.readUnsignedInt();
-                    sample.data = sampleData.subbuffer(start * 2, end * 2, true);
-                    if (sampleData24 != null)
-                        sample.data24 = sampleData24.subbuffer(start, end, true);
-                    /*
-                    sample.data = new ModelByteBuffer(sampleData, (int)(start*2),
-                            (int)((end - start)*2));
-                    if (sampleData24 != null)
-                        sample.data24 = new ModelByteBuffer(sampleData24,
-                                (int)start, (int)(end - start));
-                     */
-                    sample.startLoop = chunk.readUnsignedInt() - start;
-                    sample.endLoop = chunk.readUnsignedInt() - start;
-                    if (sample.startLoop < 0)
-                        sample.startLoop = -1;
-                    if (sample.endLoop < 0)
-                        sample.endLoop = -1;
-                    sample.sampleRate = chunk.readUnsignedInt();
-                    sample.originalPitch = chunk.readUnsignedByte();
-                    sample.pitchCorrection = chunk.readByte();
-                    sample.sampleLink = chunk.readUnsignedShort();
-                    sample.sampleType = chunk.readUnsignedShort();
-                    if (i != count - 1)
-                        this.samples.add(sample);
-                }
-            }
-        }
-
-        Iterator<SF2Layer> liter = this.layers.iterator();
-        while (liter.hasNext()) {
-            SF2Layer layer = liter.next();
-            Iterator<SF2LayerRegion> siter = layer.regions.iterator();
-            SF2Region globalsplit = null;
-            while (siter.hasNext()) {
-                SF2LayerRegion split = siter.next();
-                if (split.generators.get(SF2LayerRegion.GENERATOR_SAMPLEID) != null) {
-                    int sampleid = split.generators.get(
-                            SF2LayerRegion.GENERATOR_SAMPLEID);
-                    split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
-                    split.sample = samples.get(sampleid);
-                } else {
-                    globalsplit = split;
-                }
-            }
-            if (globalsplit != null) {
-                layer.getRegions().remove(globalsplit);
-                SF2GlobalRegion gsplit = new SF2GlobalRegion();
-                gsplit.generators = globalsplit.generators;
-                gsplit.modulators = globalsplit.modulators;
-                layer.setGlobalZone(gsplit);
-            }
-        }
-
-
-        Iterator<SF2Instrument> iiter = this.instruments.iterator();
-        while (iiter.hasNext()) {
-            SF2Instrument instrument = iiter.next();
-            Iterator<SF2InstrumentRegion> siter = instrument.regions.iterator();
-            SF2Region globalsplit = null;
-            while (siter.hasNext()) {
-                SF2InstrumentRegion split = siter.next();
-                if (split.generators.get(SF2LayerRegion.GENERATOR_INSTRUMENT) != null) {
-                    int instrumentid = split.generators.get(
-                            SF2InstrumentRegion.GENERATOR_INSTRUMENT);
-                    split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
-                    split.layer = layers.get(instrumentid);
-                } else {
-                    globalsplit = split;
-                }
-            }
-
-            if (globalsplit != null) {
-                instrument.getRegions().remove(globalsplit);
-                SF2GlobalRegion gsplit = new SF2GlobalRegion();
-                gsplit.generators = globalsplit.generators;
-                gsplit.modulators = globalsplit.modulators;
-                instrument.setGlobalZone(gsplit);
-            }
-        }
-
-    }
-
-    public void save(String name) throws IOException {
-        writeSoundbank(new RIFFWriter(name, "sfbk"));
-    }
-
-    public void save(File file) throws IOException {
-        writeSoundbank(new RIFFWriter(file, "sfbk"));
-    }
-
-    public void save(OutputStream out) throws IOException {
-        writeSoundbank(new RIFFWriter(out, "sfbk"));
-    }
-
-    private void writeSoundbank(RIFFWriter writer) throws IOException {
-        writeInfo(writer.writeList("INFO"));
-        writeSdtaChunk(writer.writeList("sdta"));
-        writePdtaChunk(writer.writeList("pdta"));
-        writer.close();
-    }
-
-    private void writeInfoStringChunk(RIFFWriter writer, String name,
-            String value) throws IOException {
-        if (value == null)
-            return;
-        RIFFWriter chunk = writer.writeChunk(name);
-        chunk.writeString(value);
-        int len = value.getBytes("ascii").length;
-        chunk.write(0);
-        len++;
-        if (len % 2 != 0)
-            chunk.write(0);
-    }
-
-    private void writeInfo(RIFFWriter writer) throws IOException {
-        if (this.targetEngine == null)
-            this.targetEngine = "EMU8000";
-        if (this.name == null)
-            this.name = "";
-
-        RIFFWriter ifil_chunk = writer.writeChunk("ifil");
-        ifil_chunk.writeUnsignedShort(this.major);
-        ifil_chunk.writeUnsignedShort(this.minor);
-        writeInfoStringChunk(writer, "isng", this.targetEngine);
-        writeInfoStringChunk(writer, "INAM", this.name);
-        writeInfoStringChunk(writer, "irom", this.romName);
-        if (romVersionMajor != -1) {
-            RIFFWriter iver_chunk = writer.writeChunk("iver");
-            iver_chunk.writeUnsignedShort(this.romVersionMajor);
-            iver_chunk.writeUnsignedShort(this.romVersionMinor);
-        }
-        writeInfoStringChunk(writer, "ICRD", this.creationDate);
-        writeInfoStringChunk(writer, "IENG", this.engineers);
-        writeInfoStringChunk(writer, "IPRD", this.product);
-        writeInfoStringChunk(writer, "ICOP", this.copyright);
-        writeInfoStringChunk(writer, "ICMT", this.comments);
-        writeInfoStringChunk(writer, "ISFT", this.tools);
-
-        writer.close();
-    }
-
-    private void writeSdtaChunk(RIFFWriter writer) throws IOException {
-
-        byte[] pad = new byte[32];
-
-        RIFFWriter smpl_chunk = writer.writeChunk("smpl");
-        for (SF2Sample sample : samples) {
-            ModelByteBuffer data = sample.getDataBuffer();
-            data.writeTo(smpl_chunk);
-            /*
-            smpl_chunk.write(data.array(),
-            data.arrayOffset(),
-            data.capacity());
-             */
-            smpl_chunk.write(pad);
-            smpl_chunk.write(pad);
-        }
-        if (major < 2)
-            return;
-        if (major == 2 && minor < 4)
-            return;
-
-
-        for (SF2Sample sample : samples) {
-            ModelByteBuffer data24 = sample.getData24Buffer();
-            if (data24 == null)
-                return;
-        }
-
-        RIFFWriter sm24_chunk = writer.writeChunk("sm24");
-        for (SF2Sample sample : samples) {
-            ModelByteBuffer data = sample.getData24Buffer();
-            data.writeTo(sm24_chunk);
-            /*
-            sm24_chunk.write(data.array(),
-            data.arrayOffset(),
-            data.capacity());*/
-            smpl_chunk.write(pad);
-        }
-    }
-
-    private void writeModulators(RIFFWriter writer, List<SF2Modulator> modulators)
-            throws IOException {
-        for (SF2Modulator modulator : modulators) {
-            writer.writeUnsignedShort(modulator.sourceOperator);
-            writer.writeUnsignedShort(modulator.destinationOperator);
-            writer.writeShort(modulator.amount);
-            writer.writeUnsignedShort(modulator.amountSourceOperator);
-            writer.writeUnsignedShort(modulator.transportOperator);
-        }
-    }
-
-    private void writeGenerators(RIFFWriter writer, Map<Integer, Short> generators)
-            throws IOException {
-        Short keyrange = (Short) generators.get(SF2Region.GENERATOR_KEYRANGE);
-        Short velrange = (Short) generators.get(SF2Region.GENERATOR_VELRANGE);
-        if (keyrange != null) {
-            writer.writeUnsignedShort(SF2Region.GENERATOR_KEYRANGE);
-            writer.writeShort(keyrange);
-        }
-        if (velrange != null) {
-            writer.writeUnsignedShort(SF2Region.GENERATOR_VELRANGE);
-            writer.writeShort(velrange);
-        }
-        for (Map.Entry<Integer, Short> generator : generators.entrySet()) {
-            if (generator.getKey() == SF2Region.GENERATOR_KEYRANGE)
-                continue;
-            if (generator.getKey() == SF2Region.GENERATOR_VELRANGE)
-                continue;
-            writer.writeUnsignedShort(generator.getKey());
-            writer.writeShort(generator.getValue());
-        }
-    }
-
-    private void writePdtaChunk(RIFFWriter writer) throws IOException {
-
-        RIFFWriter phdr_chunk = writer.writeChunk("phdr");
-        int phdr_zone_count = 0;
-        for (SF2Instrument preset : this.instruments) {
-            phdr_chunk.writeString(preset.name, 20);
-            phdr_chunk.writeUnsignedShort(preset.preset);
-            phdr_chunk.writeUnsignedShort(preset.bank);
-            phdr_chunk.writeUnsignedShort(phdr_zone_count);
-            if (preset.getGlobalRegion() != null)
-                phdr_zone_count += 1;
-            phdr_zone_count += preset.getRegions().size();
-            phdr_chunk.writeUnsignedInt(preset.library);
-            phdr_chunk.writeUnsignedInt(preset.genre);
-            phdr_chunk.writeUnsignedInt(preset.morphology);
-        }
-        phdr_chunk.writeString("EOP", 20);
-        phdr_chunk.writeUnsignedShort(0);
-        phdr_chunk.writeUnsignedShort(0);
-        phdr_chunk.writeUnsignedShort(phdr_zone_count);
-        phdr_chunk.writeUnsignedInt(0);
-        phdr_chunk.writeUnsignedInt(0);
-        phdr_chunk.writeUnsignedInt(0);
-
-
-        RIFFWriter pbag_chunk = writer.writeChunk("pbag");
-        int pbag_gencount = 0;
-        int pbag_modcount = 0;
-        for (SF2Instrument preset : this.instruments) {
-            if (preset.getGlobalRegion() != null) {
-                pbag_chunk.writeUnsignedShort(pbag_gencount);
-                pbag_chunk.writeUnsignedShort(pbag_modcount);
-                pbag_gencount += preset.getGlobalRegion().getGenerators().size();
-                pbag_modcount += preset.getGlobalRegion().getModulators().size();
-            }
-            for (SF2InstrumentRegion region : preset.getRegions()) {
-                pbag_chunk.writeUnsignedShort(pbag_gencount);
-                pbag_chunk.writeUnsignedShort(pbag_modcount);
-                if (layers.indexOf(region.layer) != -1) {
-                    // One generator is used to reference to instrument record
-                    pbag_gencount += 1;
-                }
-                pbag_gencount += region.getGenerators().size();
-                pbag_modcount += region.getModulators().size();
-
-            }
-        }
-        pbag_chunk.writeUnsignedShort(pbag_gencount);
-        pbag_chunk.writeUnsignedShort(pbag_modcount);
-
-        RIFFWriter pmod_chunk = writer.writeChunk("pmod");
-        for (SF2Instrument preset : this.instruments) {
-            if (preset.getGlobalRegion() != null) {
-                writeModulators(pmod_chunk,
-                        preset.getGlobalRegion().getModulators());
-            }
-            for (SF2InstrumentRegion region : preset.getRegions())
-                writeModulators(pmod_chunk, region.getModulators());
-        }
-        pmod_chunk.write(new byte[10]);
-
-        RIFFWriter pgen_chunk = writer.writeChunk("pgen");
-        for (SF2Instrument preset : this.instruments) {
-            if (preset.getGlobalRegion() != null) {
-                writeGenerators(pgen_chunk,
-                        preset.getGlobalRegion().getGenerators());
-            }
-            for (SF2InstrumentRegion region : preset.getRegions()) {
-                writeGenerators(pgen_chunk, region.getGenerators());
-                int ix = (int) layers.indexOf(region.layer);
-                if (ix != -1) {
-                    pgen_chunk.writeUnsignedShort(SF2Region.GENERATOR_INSTRUMENT);
-                    pgen_chunk.writeShort((short) ix);
-                }
-            }
-        }
-        pgen_chunk.write(new byte[4]);
-
-        RIFFWriter inst_chunk = writer.writeChunk("inst");
-        int inst_zone_count = 0;
-        for (SF2Layer instrument : this.layers) {
-            inst_chunk.writeString(instrument.name, 20);
-            inst_chunk.writeUnsignedShort(inst_zone_count);
-            if (instrument.getGlobalRegion() != null)
-                inst_zone_count += 1;
-            inst_zone_count += instrument.getRegions().size();
-        }
-        inst_chunk.writeString("EOI", 20);
-        inst_chunk.writeUnsignedShort(inst_zone_count);
-
-
-        RIFFWriter ibag_chunk = writer.writeChunk("ibag");
-        int ibag_gencount = 0;
-        int ibag_modcount = 0;
-        for (SF2Layer instrument : this.layers) {
-            if (instrument.getGlobalRegion() != null) {
-                ibag_chunk.writeUnsignedShort(ibag_gencount);
-                ibag_chunk.writeUnsignedShort(ibag_modcount);
-                ibag_gencount
-                        += instrument.getGlobalRegion().getGenerators().size();
-                ibag_modcount
-                        += instrument.getGlobalRegion().getModulators().size();
-            }
-            for (SF2LayerRegion region : instrument.getRegions()) {
-                ibag_chunk.writeUnsignedShort(ibag_gencount);
-                ibag_chunk.writeUnsignedShort(ibag_modcount);
-                if (samples.indexOf(region.sample) != -1) {
-                    // One generator is used to reference to instrument record
-                    ibag_gencount += 1;
-                }
-                ibag_gencount += region.getGenerators().size();
-                ibag_modcount += region.getModulators().size();
-
-            }
-        }
-        ibag_chunk.writeUnsignedShort(ibag_gencount);
-        ibag_chunk.writeUnsignedShort(ibag_modcount);
-
-
-        RIFFWriter imod_chunk = writer.writeChunk("imod");
-        for (SF2Layer instrument : this.layers) {
-            if (instrument.getGlobalRegion() != null) {
-                writeModulators(imod_chunk,
-                        instrument.getGlobalRegion().getModulators());
-            }
-            for (SF2LayerRegion region : instrument.getRegions())
-                writeModulators(imod_chunk, region.getModulators());
-        }
-        imod_chunk.write(new byte[10]);
-
-        RIFFWriter igen_chunk = writer.writeChunk("igen");
-        for (SF2Layer instrument : this.layers) {
-            if (instrument.getGlobalRegion() != null) {
-                writeGenerators(igen_chunk,
-                        instrument.getGlobalRegion().getGenerators());
-            }
-            for (SF2LayerRegion region : instrument.getRegions()) {
-                writeGenerators(igen_chunk, region.getGenerators());
-                int ix = samples.indexOf(region.sample);
-                if (ix != -1) {
-                    igen_chunk.writeUnsignedShort(SF2Region.GENERATOR_SAMPLEID);
-                    igen_chunk.writeShort((short) ix);
-                }
-            }
-        }
-        igen_chunk.write(new byte[4]);
-
-
-        RIFFWriter shdr_chunk = writer.writeChunk("shdr");
-        long sample_pos = 0;
-        for (SF2Sample sample : samples) {
-            shdr_chunk.writeString(sample.name, 20);
-            long start = sample_pos;
-            sample_pos += sample.data.capacity() / 2;
-            long end = sample_pos;
-            long startLoop = sample.startLoop + start;
-            long endLoop = sample.endLoop + start;
-            if (startLoop < start)
-                startLoop = start;
-            if (endLoop > end)
-                endLoop = end;
-            shdr_chunk.writeUnsignedInt(start);
-            shdr_chunk.writeUnsignedInt(end);
-            shdr_chunk.writeUnsignedInt(startLoop);
-            shdr_chunk.writeUnsignedInt(endLoop);
-            shdr_chunk.writeUnsignedInt(sample.sampleRate);
-            shdr_chunk.writeUnsignedByte(sample.originalPitch);
-            shdr_chunk.writeByte(sample.pitchCorrection);
-            shdr_chunk.writeUnsignedShort(sample.sampleLink);
-            shdr_chunk.writeUnsignedShort(sample.sampleType);
-            sample_pos += 32;
-        }
-        shdr_chunk.writeString("EOS", 20);
-        shdr_chunk.write(new byte[26]);
-
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public String getVersion() {
-        return major + "." + minor;
-    }
-
-    public String getVendor() {
-        return engineers;
-    }
-
-    public String getDescription() {
-        return comments;
-    }
-
-    public void setName(String s) {
-        name = s;
-    }
-
-    public void setVendor(String s) {
-        engineers = s;
-    }
-
-    public void setDescription(String s) {
-        comments = s;
-    }
-
-    public SoundbankResource[] getResources() {
-        SoundbankResource[] resources
-                = new SoundbankResource[layers.size() + samples.size()];
-        int j = 0;
-        for (int i = 0; i < layers.size(); i++)
-            resources[j++] = layers.get(i);
-        for (int i = 0; i < samples.size(); i++)
-            resources[j++] = samples.get(i);
-        return resources;
-    }
-
-    public SF2Instrument[] getInstruments() {
-        SF2Instrument[] inslist_array
-                = instruments.toArray(new SF2Instrument[instruments.size()]);
-        Arrays.sort(inslist_array, new ModelInstrumentComparator());
-        return inslist_array;
-    }
-
-    public SF2Layer[] getLayers() {
-        return layers.toArray(new SF2Layer[layers.size()]);
-    }
-
-    public SF2Sample[] getSamples() {
-        return samples.toArray(new SF2Sample[samples.size()]);
-    }
-
-    public Instrument getInstrument(Patch patch) {
-        int program = patch.getProgram();
-        int bank = patch.getBank();
-        boolean percussion = false;
-        if (patch instanceof ModelPatch)
-            percussion = ((ModelPatch)patch).isPercussion();
-        for (Instrument instrument : instruments) {
-            Patch patch2 = instrument.getPatch();
-            int program2 = patch2.getProgram();
-            int bank2 = patch2.getBank();
-            if (program == program2 && bank == bank2) {
-                boolean percussion2 = false;
-                if (patch2 instanceof ModelPatch)
-                    percussion2 = ((ModelPatch) patch2).isPercussion();
-                if (percussion == percussion2)
-                    return instrument;
-            }
-        }
-        return null;
-    }
-
-    public String getCreationDate() {
-        return creationDate;
-    }
-
-    public void setCreationDate(String creationDate) {
-        this.creationDate = creationDate;
-    }
-
-    public String getProduct() {
-        return product;
-    }
-
-    public void setProduct(String product) {
-        this.product = product;
-    }
-
-    public String getRomName() {
-        return romName;
-    }
-
-    public void setRomName(String romName) {
-        this.romName = romName;
-    }
-
-    public int getRomVersionMajor() {
-        return romVersionMajor;
-    }
-
-    public void setRomVersionMajor(int romVersionMajor) {
-        this.romVersionMajor = romVersionMajor;
-    }
-
-    public int getRomVersionMinor() {
-        return romVersionMinor;
-    }
-
-    public void setRomVersionMinor(int romVersionMinor) {
-        this.romVersionMinor = romVersionMinor;
-    }
-
-    public String getTargetEngine() {
-        return targetEngine;
-    }
-
-    public void setTargetEngine(String targetEngine) {
-        this.targetEngine = targetEngine;
-    }
-
-    public String getTools() {
-        return tools;
-    }
-
-    public void setTools(String tools) {
-        this.tools = tools;
-    }
-
-    public void addResource(SoundbankResource resource) {
-        if (resource instanceof SF2Instrument)
-            instruments.add((SF2Instrument)resource);
-        if (resource instanceof SF2Layer)
-            layers.add((SF2Layer)resource);
-        if (resource instanceof SF2Sample)
-            samples.add((SF2Sample)resource);
-    }
-
-    public void removeResource(SoundbankResource resource) {
-        if (resource instanceof SF2Instrument)
-            instruments.remove((SF2Instrument)resource);
-        if (resource instanceof SF2Layer)
-            layers.remove((SF2Layer)resource);
-        if (resource instanceof SF2Sample)
-            samples.remove((SF2Sample)resource);
-    }
-
-    public void addInstrument(SF2Instrument resource) {
-        instruments.add(resource);
-    }
-
-    public void removeInstrument(SF2Instrument resource) {
-        instruments.remove(resource);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+
+/**
+ * A SoundFont 2.04 soundbank reader.
+ *
+ * Based on SoundFont 2.04 specification from:
+ * <p>  http://developer.creative.com <br>
+ *      http://www.soundfont.com/ ;
+ *
+ * @author Karl Helgason
+ */
+public class SF2Soundbank implements Soundbank {
+
+    // version of the Sound Font RIFF file
+    protected int major = 2;
+    protected int minor = 1;
+    // target Sound Engine
+    protected String targetEngine = "EMU8000";
+    // Sound Font Bank Name
+    protected String name = "untitled";
+    // Sound ROM Name
+    protected String romName = null;
+    // Sound ROM Version
+    protected int romVersionMajor = -1;
+    protected int romVersionMinor = -1;
+    // Date of Creation of the Bank
+    protected String creationDate = null;
+    // Sound Designers and Engineers for the Bank
+    protected String engineers = null;
+    // Product for which the Bank was intended
+    protected String product = null;
+    // Copyright message
+    protected String copyright = null;
+    // Comments
+    protected String comments = null;
+    // The SoundFont tools used to create and alter the bank
+    protected String tools = null;
+    // The Sample Data loaded from the SoundFont
+    private ModelByteBuffer sampleData = null;
+    private ModelByteBuffer sampleData24 = null;
+    private File sampleFile = null;
+    private boolean largeFormat = false;
+    private List<SF2Instrument> instruments = new ArrayList<SF2Instrument>();
+    private List<SF2Layer> layers = new ArrayList<SF2Layer>();
+    private List<SF2Sample> samples = new ArrayList<SF2Sample>();
+
+    public SF2Soundbank() {
+    }
+
+    public SF2Soundbank(URL url) throws IOException {
+
+        InputStream is = url.openStream();
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public SF2Soundbank(File file) throws IOException {
+        largeFormat = true;
+        sampleFile = file;
+        InputStream is = new FileInputStream(file);
+        try {
+            readSoundbank(is);
+        } finally {
+            is.close();
+        }
+    }
+
+    public SF2Soundbank(InputStream inputstream) throws IOException {
+        readSoundbank(inputstream);
+    }
+
+    private void readSoundbank(InputStream inputstream) throws IOException {
+        RIFFReader riff = new RIFFReader(inputstream);
+        if (!riff.getFormat().equals("RIFF")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid RIFF stream!");
+        }
+        if (!riff.getType().equals("sfbk")) {
+            throw new RIFFInvalidFormatException(
+                    "Input stream is not a valid SoundFont!");
+        }
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("LIST")) {
+                if (chunk.getType().equals("INFO"))
+                    readInfoChunk(chunk);
+                if (chunk.getType().equals("sdta"))
+                    readSdtaChunk(chunk);
+                if (chunk.getType().equals("pdta"))
+                    readPdtaChunk(chunk);
+            }
+        }
+    }
+
+    private void readInfoChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("ifil")) {
+                major = chunk.readUnsignedShort();
+                minor = chunk.readUnsignedShort();
+            } else if (format.equals("isng")) {
+                this.targetEngine = chunk.readString(chunk.available());
+            } else if (format.equals("INAM")) {
+                this.name = chunk.readString(chunk.available());
+            } else if (format.equals("irom")) {
+                this.romName = chunk.readString(chunk.available());
+            } else if (format.equals("iver")) {
+                romVersionMajor = chunk.readUnsignedShort();
+                romVersionMinor = chunk.readUnsignedShort();
+            } else if (format.equals("ICRD")) {
+                this.creationDate = chunk.readString(chunk.available());
+            } else if (format.equals("IENG")) {
+                this.engineers = chunk.readString(chunk.available());
+            } else if (format.equals("IPRD")) {
+                this.product = chunk.readString(chunk.available());
+            } else if (format.equals("ICOP")) {
+                this.copyright = chunk.readString(chunk.available());
+            } else if (format.equals("ICMT")) {
+                this.comments = chunk.readString(chunk.available());
+            } else if (format.equals("ISFT")) {
+                this.tools = chunk.readString(chunk.available());
+            }
+
+        }
+    }
+
+    private void readSdtaChunk(RIFFReader riff) throws IOException {
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            if (chunk.getFormat().equals("smpl")) {
+                if (!largeFormat) {
+                    byte[] sampleData = new byte[chunk.available()];
+
+                    int read = 0;
+                    int avail = chunk.available();
+                    while (read != avail) {
+                        if (avail - read > 65536) {
+                            chunk.read(sampleData, read, 65536);
+                            read += 65536;
+                        } else {
+                            chunk.read(sampleData, read, avail - read);
+                            read = avail;
+                        }
+
+                    }
+                    this.sampleData = new ModelByteBuffer(sampleData);
+                    //chunk.read(sampleData);
+                } else {
+                    this.sampleData = new ModelByteBuffer(sampleFile,
+                            chunk.getFilePointer(), chunk.available());
+                }
+            }
+            if (chunk.getFormat().equals("sm24")) {
+                if (!largeFormat) {
+                    byte[] sampleData24 = new byte[chunk.available()];
+                    //chunk.read(sampleData24);
+
+                    int read = 0;
+                    int avail = chunk.available();
+                    while (read != avail) {
+                        if (avail - read > 65536) {
+                            chunk.read(sampleData24, read, 65536);
+                            read += 65536;
+                        } else {
+                            chunk.read(sampleData24, read, avail - read);
+                            read = avail;
+                        }
+
+                    }
+                    this.sampleData24 = new ModelByteBuffer(sampleData24);
+                } else {
+                    this.sampleData24 = new ModelByteBuffer(sampleFile,
+                            chunk.getFilePointer(), chunk.available());
+                }
+
+            }
+        }
+    }
+
+    private void readPdtaChunk(RIFFReader riff) throws IOException {
+
+        List<SF2Instrument> presets = new ArrayList<SF2Instrument>();
+        List<Integer> presets_bagNdx = new ArrayList<Integer>();
+        List<SF2InstrumentRegion> presets_splits_gen
+                = new ArrayList<SF2InstrumentRegion>();
+        List<SF2InstrumentRegion> presets_splits_mod
+                = new ArrayList<SF2InstrumentRegion>();
+
+        List<SF2Layer> instruments = new ArrayList<SF2Layer>();
+        List<Integer> instruments_bagNdx = new ArrayList<Integer>();
+        List<SF2LayerRegion> instruments_splits_gen
+                = new ArrayList<SF2LayerRegion>();
+        List<SF2LayerRegion> instruments_splits_mod
+                = new ArrayList<SF2LayerRegion>();
+
+        while (riff.hasNextChunk()) {
+            RIFFReader chunk = riff.nextChunk();
+            String format = chunk.getFormat();
+            if (format.equals("phdr")) {
+                // Preset Header / Instrument
+                if (chunk.available() % 38 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 38;
+                for (int i = 0; i < count; i++) {
+                    SF2Instrument preset = new SF2Instrument(this);
+                    preset.name = chunk.readString(20);
+                    preset.preset = chunk.readUnsignedShort();
+                    preset.bank = chunk.readUnsignedShort();
+                    presets_bagNdx.add(chunk.readUnsignedShort());
+                    preset.library = chunk.readUnsignedInt();
+                    preset.genre = chunk.readUnsignedInt();
+                    preset.morphology = chunk.readUnsignedInt();
+                    presets.add(preset);
+                    if (i != count - 1)
+                        this.instruments.add(preset);
+                }
+            } else if (format.equals("pbag")) {
+                // Preset Zones / Instruments splits
+                if (chunk.available() % 4 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 4;
+
+                // Skip first record
+                {
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (presets_splits_gen.size() < gencount)
+                        presets_splits_gen.add(null);
+                    while (presets_splits_mod.size() < modcount)
+                        presets_splits_mod.add(null);
+                    count--;
+                }
+
+                int offset = presets_bagNdx.get(0);
+                // Offset should be 0 (but just case)
+                for (int i = 0; i < offset; i++) {
+                    if (count == 0)
+                        throw new RIFFInvalidDataException();
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (presets_splits_gen.size() < gencount)
+                        presets_splits_gen.add(null);
+                    while (presets_splits_mod.size() < modcount)
+                        presets_splits_mod.add(null);
+                    count--;
+                }
+
+                for (int i = 0; i < presets_bagNdx.size() - 1; i++) {
+                    int zone_count = presets_bagNdx.get(i + 1)
+                                     - presets_bagNdx.get(i);
+                    SF2Instrument preset = presets.get(i);
+                    for (int ii = 0; ii < zone_count; ii++) {
+                        if (count == 0)
+                            throw new RIFFInvalidDataException();
+                        int gencount = chunk.readUnsignedShort();
+                        int modcount = chunk.readUnsignedShort();
+                        SF2InstrumentRegion split = new SF2InstrumentRegion();
+                        preset.regions.add(split);
+                        while (presets_splits_gen.size() < gencount)
+                            presets_splits_gen.add(split);
+                        while (presets_splits_mod.size() < modcount)
+                            presets_splits_mod.add(split);
+                        count--;
+                    }
+                }
+            } else if (format.equals("pmod")) {
+                // Preset Modulators / Split Modulators
+                for (int i = 0; i < presets_splits_mod.size(); i++) {
+                    SF2Modulator modulator = new SF2Modulator();
+                    modulator.sourceOperator = chunk.readUnsignedShort();
+                    modulator.destinationOperator = chunk.readUnsignedShort();
+                    modulator.amount = chunk.readShort();
+                    modulator.amountSourceOperator = chunk.readUnsignedShort();
+                    modulator.transportOperator = chunk.readUnsignedShort();
+                    SF2InstrumentRegion split = presets_splits_mod.get(i);
+                    if (split != null)
+                        split.modulators.add(modulator);
+                }
+            } else if (format.equals("pgen")) {
+                // Preset Generators / Split Generators
+                for (int i = 0; i < presets_splits_gen.size(); i++) {
+                    int operator = chunk.readUnsignedShort();
+                    short amount = chunk.readShort();
+                    SF2InstrumentRegion split = presets_splits_gen.get(i);
+                    if (split != null)
+                        split.generators.put(operator, amount);
+                }
+            } else if (format.equals("inst")) {
+                // Instrument Header / Layers
+                if (chunk.available() % 22 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 22;
+                for (int i = 0; i < count; i++) {
+                    SF2Layer layer = new SF2Layer(this);
+                    layer.name = chunk.readString(20);
+                    instruments_bagNdx.add(chunk.readUnsignedShort());
+                    instruments.add(layer);
+                    if (i != count - 1)
+                        this.layers.add(layer);
+                }
+            } else if (format.equals("ibag")) {
+                // Instrument Zones / Layer splits
+                if (chunk.available() % 4 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 4;
+
+                // Skip first record
+                {
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (instruments_splits_gen.size() < gencount)
+                        instruments_splits_gen.add(null);
+                    while (instruments_splits_mod.size() < modcount)
+                        instruments_splits_mod.add(null);
+                    count--;
+                }
+
+                int offset = instruments_bagNdx.get(0);
+                // Offset should be 0 (but just case)
+                for (int i = 0; i < offset; i++) {
+                    if (count == 0)
+                        throw new RIFFInvalidDataException();
+                    int gencount = chunk.readUnsignedShort();
+                    int modcount = chunk.readUnsignedShort();
+                    while (instruments_splits_gen.size() < gencount)
+                        instruments_splits_gen.add(null);
+                    while (instruments_splits_mod.size() < modcount)
+                        instruments_splits_mod.add(null);
+                    count--;
+                }
+
+                for (int i = 0; i < instruments_bagNdx.size() - 1; i++) {
+                    int zone_count = instruments_bagNdx.get(i + 1) - instruments_bagNdx.get(i);
+                    SF2Layer layer = layers.get(i);
+                    for (int ii = 0; ii < zone_count; ii++) {
+                        if (count == 0)
+                            throw new RIFFInvalidDataException();
+                        int gencount = chunk.readUnsignedShort();
+                        int modcount = chunk.readUnsignedShort();
+                        SF2LayerRegion split = new SF2LayerRegion();
+                        layer.regions.add(split);
+                        while (instruments_splits_gen.size() < gencount)
+                            instruments_splits_gen.add(split);
+                        while (instruments_splits_mod.size() < modcount)
+                            instruments_splits_mod.add(split);
+                        count--;
+                    }
+                }
+
+            } else if (format.equals("imod")) {
+                // Instrument Modulators / Split Modulators
+                for (int i = 0; i < instruments_splits_mod.size(); i++) {
+                    SF2Modulator modulator = new SF2Modulator();
+                    modulator.sourceOperator = chunk.readUnsignedShort();
+                    modulator.destinationOperator = chunk.readUnsignedShort();
+                    modulator.amount = chunk.readShort();
+                    modulator.amountSourceOperator = chunk.readUnsignedShort();
+                    modulator.transportOperator = chunk.readUnsignedShort();
+                    SF2LayerRegion split = instruments_splits_gen.get(i);
+                    if (split != null)
+                        split.modulators.add(modulator);
+                }
+            } else if (format.equals("igen")) {
+                // Instrument Generators / Split Generators
+                for (int i = 0; i < instruments_splits_gen.size(); i++) {
+                    int operator = chunk.readUnsignedShort();
+                    short amount = chunk.readShort();
+                    SF2LayerRegion split = instruments_splits_gen.get(i);
+                    if (split != null)
+                        split.generators.put(operator, amount);
+                }
+            } else if (format.equals("shdr")) {
+                // Sample Headers
+                if (chunk.available() % 46 != 0)
+                    throw new RIFFInvalidDataException();
+                int count = chunk.available() / 46;
+                for (int i = 0; i < count; i++) {
+                    SF2Sample sample = new SF2Sample(this);
+                    sample.name = chunk.readString(20);
+                    long start = chunk.readUnsignedInt();
+                    long end = chunk.readUnsignedInt();
+                    sample.data = sampleData.subbuffer(start * 2, end * 2, true);
+                    if (sampleData24 != null)
+                        sample.data24 = sampleData24.subbuffer(start, end, true);
+                    /*
+                    sample.data = new ModelByteBuffer(sampleData, (int)(start*2),
+                            (int)((end - start)*2));
+                    if (sampleData24 != null)
+                        sample.data24 = new ModelByteBuffer(sampleData24,
+                                (int)start, (int)(end - start));
+                     */
+                    sample.startLoop = chunk.readUnsignedInt() - start;
+                    sample.endLoop = chunk.readUnsignedInt() - start;
+                    if (sample.startLoop < 0)
+                        sample.startLoop = -1;
+                    if (sample.endLoop < 0)
+                        sample.endLoop = -1;
+                    sample.sampleRate = chunk.readUnsignedInt();
+                    sample.originalPitch = chunk.readUnsignedByte();
+                    sample.pitchCorrection = chunk.readByte();
+                    sample.sampleLink = chunk.readUnsignedShort();
+                    sample.sampleType = chunk.readUnsignedShort();
+                    if (i != count - 1)
+                        this.samples.add(sample);
+                }
+            }
+        }
+
+        Iterator<SF2Layer> liter = this.layers.iterator();
+        while (liter.hasNext()) {
+            SF2Layer layer = liter.next();
+            Iterator<SF2LayerRegion> siter = layer.regions.iterator();
+            SF2Region globalsplit = null;
+            while (siter.hasNext()) {
+                SF2LayerRegion split = siter.next();
+                if (split.generators.get(SF2LayerRegion.GENERATOR_SAMPLEID) != null) {
+                    int sampleid = split.generators.get(
+                            SF2LayerRegion.GENERATOR_SAMPLEID);
+                    split.generators.remove(SF2LayerRegion.GENERATOR_SAMPLEID);
+                    split.sample = samples.get(sampleid);
+                } else {
+                    globalsplit = split;
+                }
+            }
+            if (globalsplit != null) {
+                layer.getRegions().remove(globalsplit);
+                SF2GlobalRegion gsplit = new SF2GlobalRegion();
+                gsplit.generators = globalsplit.generators;
+                gsplit.modulators = globalsplit.modulators;
+                layer.setGlobalZone(gsplit);
+            }
+        }
+
+
+        Iterator<SF2Instrument> iiter = this.instruments.iterator();
+        while (iiter.hasNext()) {
+            SF2Instrument instrument = iiter.next();
+            Iterator<SF2InstrumentRegion> siter = instrument.regions.iterator();
+            SF2Region globalsplit = null;
+            while (siter.hasNext()) {
+                SF2InstrumentRegion split = siter.next();
+                if (split.generators.get(SF2LayerRegion.GENERATOR_INSTRUMENT) != null) {
+                    int instrumentid = split.generators.get(
+                            SF2InstrumentRegion.GENERATOR_INSTRUMENT);
+                    split.generators.remove(SF2LayerRegion.GENERATOR_INSTRUMENT);
+                    split.layer = layers.get(instrumentid);
+                } else {
+                    globalsplit = split;
+                }
+            }
+
+            if (globalsplit != null) {
+                instrument.getRegions().remove(globalsplit);
+                SF2GlobalRegion gsplit = new SF2GlobalRegion();
+                gsplit.generators = globalsplit.generators;
+                gsplit.modulators = globalsplit.modulators;
+                instrument.setGlobalZone(gsplit);
+            }
+        }
+
+    }
+
+    public void save(String name) throws IOException {
+        writeSoundbank(new RIFFWriter(name, "sfbk"));
+    }
+
+    public void save(File file) throws IOException {
+        writeSoundbank(new RIFFWriter(file, "sfbk"));
+    }
+
+    public void save(OutputStream out) throws IOException {
+        writeSoundbank(new RIFFWriter(out, "sfbk"));
+    }
+
+    private void writeSoundbank(RIFFWriter writer) throws IOException {
+        writeInfo(writer.writeList("INFO"));
+        writeSdtaChunk(writer.writeList("sdta"));
+        writePdtaChunk(writer.writeList("pdta"));
+        writer.close();
+    }
+
+    private void writeInfoStringChunk(RIFFWriter writer, String name,
+            String value) throws IOException {
+        if (value == null)
+            return;
+        RIFFWriter chunk = writer.writeChunk(name);
+        chunk.writeString(value);
+        int len = value.getBytes("ascii").length;
+        chunk.write(0);
+        len++;
+        if (len % 2 != 0)
+            chunk.write(0);
+    }
+
+    private void writeInfo(RIFFWriter writer) throws IOException {
+        if (this.targetEngine == null)
+            this.targetEngine = "EMU8000";
+        if (this.name == null)
+            this.name = "";
+
+        RIFFWriter ifil_chunk = writer.writeChunk("ifil");
+        ifil_chunk.writeUnsignedShort(this.major);
+        ifil_chunk.writeUnsignedShort(this.minor);
+        writeInfoStringChunk(writer, "isng", this.targetEngine);
+        writeInfoStringChunk(writer, "INAM", this.name);
+        writeInfoStringChunk(writer, "irom", this.romName);
+        if (romVersionMajor != -1) {
+            RIFFWriter iver_chunk = writer.writeChunk("iver");
+            iver_chunk.writeUnsignedShort(this.romVersionMajor);
+            iver_chunk.writeUnsignedShort(this.romVersionMinor);
+        }
+        writeInfoStringChunk(writer, "ICRD", this.creationDate);
+        writeInfoStringChunk(writer, "IENG", this.engineers);
+        writeInfoStringChunk(writer, "IPRD", this.product);
+        writeInfoStringChunk(writer, "ICOP", this.copyright);
+        writeInfoStringChunk(writer, "ICMT", this.comments);
+        writeInfoStringChunk(writer, "ISFT", this.tools);
+
+        writer.close();
+    }
+
+    private void writeSdtaChunk(RIFFWriter writer) throws IOException {
+
+        byte[] pad = new byte[32];
+
+        RIFFWriter smpl_chunk = writer.writeChunk("smpl");
+        for (SF2Sample sample : samples) {
+            ModelByteBuffer data = sample.getDataBuffer();
+            data.writeTo(smpl_chunk);
+            /*
+            smpl_chunk.write(data.array(),
+            data.arrayOffset(),
+            data.capacity());
+             */
+            smpl_chunk.write(pad);
+            smpl_chunk.write(pad);
+        }
+        if (major < 2)
+            return;
+        if (major == 2 && minor < 4)
+            return;
+
+
+        for (SF2Sample sample : samples) {
+            ModelByteBuffer data24 = sample.getData24Buffer();
+            if (data24 == null)
+                return;
+        }
+
+        RIFFWriter sm24_chunk = writer.writeChunk("sm24");
+        for (SF2Sample sample : samples) {
+            ModelByteBuffer data = sample.getData24Buffer();
+            data.writeTo(sm24_chunk);
+            /*
+            sm24_chunk.write(data.array(),
+            data.arrayOffset(),
+            data.capacity());*/
+            smpl_chunk.write(pad);
+        }
+    }
+
+    private void writeModulators(RIFFWriter writer, List<SF2Modulator> modulators)
+            throws IOException {
+        for (SF2Modulator modulator : modulators) {
+            writer.writeUnsignedShort(modulator.sourceOperator);
+            writer.writeUnsignedShort(modulator.destinationOperator);
+            writer.writeShort(modulator.amount);
+            writer.writeUnsignedShort(modulator.amountSourceOperator);
+            writer.writeUnsignedShort(modulator.transportOperator);
+        }
+    }
+
+    private void writeGenerators(RIFFWriter writer, Map<Integer, Short> generators)
+            throws IOException {
+        Short keyrange = (Short) generators.get(SF2Region.GENERATOR_KEYRANGE);
+        Short velrange = (Short) generators.get(SF2Region.GENERATOR_VELRANGE);
+        if (keyrange != null) {
+            writer.writeUnsignedShort(SF2Region.GENERATOR_KEYRANGE);
+            writer.writeShort(keyrange);
+        }
+        if (velrange != null) {
+            writer.writeUnsignedShort(SF2Region.GENERATOR_VELRANGE);
+            writer.writeShort(velrange);
+        }
+        for (Map.Entry<Integer, Short> generator : generators.entrySet()) {
+            if (generator.getKey() == SF2Region.GENERATOR_KEYRANGE)
+                continue;
+            if (generator.getKey() == SF2Region.GENERATOR_VELRANGE)
+                continue;
+            writer.writeUnsignedShort(generator.getKey());
+            writer.writeShort(generator.getValue());
+        }
+    }
+
+    private void writePdtaChunk(RIFFWriter writer) throws IOException {
+
+        RIFFWriter phdr_chunk = writer.writeChunk("phdr");
+        int phdr_zone_count = 0;
+        for (SF2Instrument preset : this.instruments) {
+            phdr_chunk.writeString(preset.name, 20);
+            phdr_chunk.writeUnsignedShort(preset.preset);
+            phdr_chunk.writeUnsignedShort(preset.bank);
+            phdr_chunk.writeUnsignedShort(phdr_zone_count);
+            if (preset.getGlobalRegion() != null)
+                phdr_zone_count += 1;
+            phdr_zone_count += preset.getRegions().size();
+            phdr_chunk.writeUnsignedInt(preset.library);
+            phdr_chunk.writeUnsignedInt(preset.genre);
+            phdr_chunk.writeUnsignedInt(preset.morphology);
+        }
+        phdr_chunk.writeString("EOP", 20);
+        phdr_chunk.writeUnsignedShort(0);
+        phdr_chunk.writeUnsignedShort(0);
+        phdr_chunk.writeUnsignedShort(phdr_zone_count);
+        phdr_chunk.writeUnsignedInt(0);
+        phdr_chunk.writeUnsignedInt(0);
+        phdr_chunk.writeUnsignedInt(0);
+
+
+        RIFFWriter pbag_chunk = writer.writeChunk("pbag");
+        int pbag_gencount = 0;
+        int pbag_modcount = 0;
+        for (SF2Instrument preset : this.instruments) {
+            if (preset.getGlobalRegion() != null) {
+                pbag_chunk.writeUnsignedShort(pbag_gencount);
+                pbag_chunk.writeUnsignedShort(pbag_modcount);
+                pbag_gencount += preset.getGlobalRegion().getGenerators().size();
+                pbag_modcount += preset.getGlobalRegion().getModulators().size();
+            }
+            for (SF2InstrumentRegion region : preset.getRegions()) {
+                pbag_chunk.writeUnsignedShort(pbag_gencount);
+                pbag_chunk.writeUnsignedShort(pbag_modcount);
+                if (layers.indexOf(region.layer) != -1) {
+                    // One generator is used to reference to instrument record
+                    pbag_gencount += 1;
+                }
+                pbag_gencount += region.getGenerators().size();
+                pbag_modcount += region.getModulators().size();
+
+            }
+        }
+        pbag_chunk.writeUnsignedShort(pbag_gencount);
+        pbag_chunk.writeUnsignedShort(pbag_modcount);
+
+        RIFFWriter pmod_chunk = writer.writeChunk("pmod");
+        for (SF2Instrument preset : this.instruments) {
+            if (preset.getGlobalRegion() != null) {
+                writeModulators(pmod_chunk,
+                        preset.getGlobalRegion().getModulators());
+            }
+            for (SF2InstrumentRegion region : preset.getRegions())
+                writeModulators(pmod_chunk, region.getModulators());
+        }
+        pmod_chunk.write(new byte[10]);
+
+        RIFFWriter pgen_chunk = writer.writeChunk("pgen");
+        for (SF2Instrument preset : this.instruments) {
+            if (preset.getGlobalRegion() != null) {
+                writeGenerators(pgen_chunk,
+                        preset.getGlobalRegion().getGenerators());
+            }
+            for (SF2InstrumentRegion region : preset.getRegions()) {
+                writeGenerators(pgen_chunk, region.getGenerators());
+                int ix = (int) layers.indexOf(region.layer);
+                if (ix != -1) {
+                    pgen_chunk.writeUnsignedShort(SF2Region.GENERATOR_INSTRUMENT);
+                    pgen_chunk.writeShort((short) ix);
+                }
+            }
+        }
+        pgen_chunk.write(new byte[4]);
+
+        RIFFWriter inst_chunk = writer.writeChunk("inst");
+        int inst_zone_count = 0;
+        for (SF2Layer instrument : this.layers) {
+            inst_chunk.writeString(instrument.name, 20);
+            inst_chunk.writeUnsignedShort(inst_zone_count);
+            if (instrument.getGlobalRegion() != null)
+                inst_zone_count += 1;
+            inst_zone_count += instrument.getRegions().size();
+        }
+        inst_chunk.writeString("EOI", 20);
+        inst_chunk.writeUnsignedShort(inst_zone_count);
+
+
+        RIFFWriter ibag_chunk = writer.writeChunk("ibag");
+        int ibag_gencount = 0;
+        int ibag_modcount = 0;
+        for (SF2Layer instrument : this.layers) {
+            if (instrument.getGlobalRegion() != null) {
+                ibag_chunk.writeUnsignedShort(ibag_gencount);
+                ibag_chunk.writeUnsignedShort(ibag_modcount);
+                ibag_gencount
+                        += instrument.getGlobalRegion().getGenerators().size();
+                ibag_modcount
+                        += instrument.getGlobalRegion().getModulators().size();
+            }
+            for (SF2LayerRegion region : instrument.getRegions()) {
+                ibag_chunk.writeUnsignedShort(ibag_gencount);
+                ibag_chunk.writeUnsignedShort(ibag_modcount);
+                if (samples.indexOf(region.sample) != -1) {
+                    // One generator is used to reference to instrument record
+                    ibag_gencount += 1;
+                }
+                ibag_gencount += region.getGenerators().size();
+                ibag_modcount += region.getModulators().size();
+
+            }
+        }
+        ibag_chunk.writeUnsignedShort(ibag_gencount);
+        ibag_chunk.writeUnsignedShort(ibag_modcount);
+
+
+        RIFFWriter imod_chunk = writer.writeChunk("imod");
+        for (SF2Layer instrument : this.layers) {
+            if (instrument.getGlobalRegion() != null) {
+                writeModulators(imod_chunk,
+                        instrument.getGlobalRegion().getModulators());
+            }
+            for (SF2LayerRegion region : instrument.getRegions())
+                writeModulators(imod_chunk, region.getModulators());
+        }
+        imod_chunk.write(new byte[10]);
+
+        RIFFWriter igen_chunk = writer.writeChunk("igen");
+        for (SF2Layer instrument : this.layers) {
+            if (instrument.getGlobalRegion() != null) {
+                writeGenerators(igen_chunk,
+                        instrument.getGlobalRegion().getGenerators());
+            }
+            for (SF2LayerRegion region : instrument.getRegions()) {
+                writeGenerators(igen_chunk, region.getGenerators());
+                int ix = samples.indexOf(region.sample);
+                if (ix != -1) {
+                    igen_chunk.writeUnsignedShort(SF2Region.GENERATOR_SAMPLEID);
+                    igen_chunk.writeShort((short) ix);
+                }
+            }
+        }
+        igen_chunk.write(new byte[4]);
+
+
+        RIFFWriter shdr_chunk = writer.writeChunk("shdr");
+        long sample_pos = 0;
+        for (SF2Sample sample : samples) {
+            shdr_chunk.writeString(sample.name, 20);
+            long start = sample_pos;
+            sample_pos += sample.data.capacity() / 2;
+            long end = sample_pos;
+            long startLoop = sample.startLoop + start;
+            long endLoop = sample.endLoop + start;
+            if (startLoop < start)
+                startLoop = start;
+            if (endLoop > end)
+                endLoop = end;
+            shdr_chunk.writeUnsignedInt(start);
+            shdr_chunk.writeUnsignedInt(end);
+            shdr_chunk.writeUnsignedInt(startLoop);
+            shdr_chunk.writeUnsignedInt(endLoop);
+            shdr_chunk.writeUnsignedInt(sample.sampleRate);
+            shdr_chunk.writeUnsignedByte(sample.originalPitch);
+            shdr_chunk.writeByte(sample.pitchCorrection);
+            shdr_chunk.writeUnsignedShort(sample.sampleLink);
+            shdr_chunk.writeUnsignedShort(sample.sampleType);
+            sample_pos += 32;
+        }
+        shdr_chunk.writeString("EOS", 20);
+        shdr_chunk.write(new byte[26]);
+
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getVersion() {
+        return major + "." + minor;
+    }
+
+    public String getVendor() {
+        return engineers;
+    }
+
+    public String getDescription() {
+        return comments;
+    }
+
+    public void setName(String s) {
+        name = s;
+    }
+
+    public void setVendor(String s) {
+        engineers = s;
+    }
+
+    public void setDescription(String s) {
+        comments = s;
+    }
+
+    public SoundbankResource[] getResources() {
+        SoundbankResource[] resources
+                = new SoundbankResource[layers.size() + samples.size()];
+        int j = 0;
+        for (int i = 0; i < layers.size(); i++)
+            resources[j++] = layers.get(i);
+        for (int i = 0; i < samples.size(); i++)
+            resources[j++] = samples.get(i);
+        return resources;
+    }
+
+    public SF2Instrument[] getInstruments() {
+        SF2Instrument[] inslist_array
+                = instruments.toArray(new SF2Instrument[instruments.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public SF2Layer[] getLayers() {
+        return layers.toArray(new SF2Layer[layers.size()]);
+    }
+
+    public SF2Sample[] getSamples() {
+        return samples.toArray(new SF2Sample[samples.size()]);
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch)patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch) patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public String getCreationDate() {
+        return creationDate;
+    }
+
+    public void setCreationDate(String creationDate) {
+        this.creationDate = creationDate;
+    }
+
+    public String getProduct() {
+        return product;
+    }
+
+    public void setProduct(String product) {
+        this.product = product;
+    }
+
+    public String getRomName() {
+        return romName;
+    }
+
+    public void setRomName(String romName) {
+        this.romName = romName;
+    }
+
+    public int getRomVersionMajor() {
+        return romVersionMajor;
+    }
+
+    public void setRomVersionMajor(int romVersionMajor) {
+        this.romVersionMajor = romVersionMajor;
+    }
+
+    public int getRomVersionMinor() {
+        return romVersionMinor;
+    }
+
+    public void setRomVersionMinor(int romVersionMinor) {
+        this.romVersionMinor = romVersionMinor;
+    }
+
+    public String getTargetEngine() {
+        return targetEngine;
+    }
+
+    public void setTargetEngine(String targetEngine) {
+        this.targetEngine = targetEngine;
+    }
+
+    public String getTools() {
+        return tools;
+    }
+
+    public void setTools(String tools) {
+        this.tools = tools;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof SF2Instrument)
+            instruments.add((SF2Instrument)resource);
+        if (resource instanceof SF2Layer)
+            layers.add((SF2Layer)resource);
+        if (resource instanceof SF2Sample)
+            samples.add((SF2Sample)resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof SF2Instrument)
+            instruments.remove((SF2Instrument)resource);
+        if (resource instanceof SF2Layer)
+            layers.remove((SF2Layer)resource);
+        if (resource instanceof SF2Sample)
+            samples.remove((SF2Sample)resource);
+    }
+
+    public void addInstrument(SF2Instrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(SF2Instrument resource) {
+        instruments.remove(resource);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SF2SoundbankReader.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SF2SoundbankReader.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,73 +1,73 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.spi.SoundbankReader;
-
-/**
- * This class is used to connect the SF2SoundBank class
- * to the SoundbankReader SPI interface.
- *
- * @author Karl Helgason
- */
-public class SF2SoundbankReader extends SoundbankReader {
-
-    public Soundbank getSoundbank(URL url)
-            throws InvalidMidiDataException, IOException {
-        try {
-            return new SF2Soundbank(url);
-        } catch (RIFFInvalidFormatException e) {
-            return null;
-        }
-    }
-
-    public Soundbank getSoundbank(InputStream stream)
-            throws InvalidMidiDataException, IOException {
-        try {
-            stream.mark(512);
-            return new SF2Soundbank(stream);
-        } catch (RIFFInvalidFormatException e) {
-            stream.reset();
-            return null;
-        }
-    }
-
-    public Soundbank getSoundbank(File file)
-            throws InvalidMidiDataException, IOException {
-        if (!file.getPath().toLowerCase().endsWith(".sf2"))
-            return null;
-        try {
-            return new SF2Soundbank(file);
-        } catch (RIFFInvalidFormatException e) {
-            return null;
-        }
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.spi.SoundbankReader;
+
+/**
+ * This class is used to connect the SF2SoundBank class
+ * to the SoundbankReader SPI interface.
+ *
+ * @author Karl Helgason
+ */
+public class SF2SoundbankReader extends SoundbankReader {
+
+    public Soundbank getSoundbank(URL url)
+            throws InvalidMidiDataException, IOException {
+        try {
+            return new SF2Soundbank(url);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(InputStream stream)
+            throws InvalidMidiDataException, IOException {
+        try {
+            stream.mark(512);
+            return new SF2Soundbank(stream);
+        } catch (RIFFInvalidFormatException e) {
+            stream.reset();
+            return null;
+        }
+    }
+
+    public Soundbank getSoundbank(File file)
+            throws InvalidMidiDataException, IOException {
+        if (!file.getPath().toLowerCase().endsWith(".sf2"))
+            return null;
+        try {
+            return new SF2Soundbank(file);
+        } catch (RIFFInvalidFormatException e) {
+            return null;
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SimpleInstrument.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SimpleInstrument.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,196 +1,196 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.sound.midi.Patch;
-
-/**
- * A simple instrument that is made of other ModelInstrument, ModelPerformer
- * objects.
- *
- * @author Karl Helgason
- */
-public class SimpleInstrument extends ModelInstrument {
-
-    protected class SimpleInstrumentPart {
-        ModelPerformer[] performers;
-        int keyFrom;
-        int keyTo;
-        int velFrom;
-        int velTo;
-        int exclusiveClass;
-    }
-    protected int preset = 0;
-    protected int bank = 0;
-    protected boolean percussion = false;
-    protected String name = "";
-    protected List<SimpleInstrumentPart> parts
-            = new ArrayList<SimpleInstrumentPart>();
-
-    public SimpleInstrument() {
-        super(null, null, null, null);
-    }
-
-    public void clear() {
-        parts.clear();
-    }
-
-    public void add(ModelPerformer[] performers, int keyFrom, int keyTo,
-            int velFrom, int velTo, int exclusiveClass) {
-        SimpleInstrumentPart part = new SimpleInstrumentPart();
-        part.performers = performers;
-        part.keyFrom = keyFrom;
-        part.keyTo = keyTo;
-        part.velFrom = velFrom;
-        part.velTo = velTo;
-        part.exclusiveClass = exclusiveClass;
-        parts.add(part);
-    }
-
-    public void add(ModelPerformer[] performers, int keyFrom, int keyTo,
-            int velFrom, int velTo) {
-        add(performers, keyFrom, keyTo, velFrom, velTo, -1);
-    }
-
-    public void add(ModelPerformer[] performers, int keyFrom, int keyTo) {
-        add(performers, keyFrom, keyTo, 0, 127, -1);
-    }
-
-    public void add(ModelPerformer[] performers) {
-        add(performers, 0, 127, 0, 127, -1);
-    }
-
-    public void add(ModelPerformer performer, int keyFrom, int keyTo,
-            int velFrom, int velTo, int exclusiveClass) {
-        add(new ModelPerformer[]{performer}, keyFrom, keyTo, velFrom, velTo,
-                exclusiveClass);
-    }
-
-    public void add(ModelPerformer performer, int keyFrom, int keyTo,
-            int velFrom, int velTo) {
-        add(new ModelPerformer[]{performer}, keyFrom, keyTo, velFrom, velTo);
-    }
-
-    public void add(ModelPerformer performer, int keyFrom, int keyTo) {
-        add(new ModelPerformer[]{performer}, keyFrom, keyTo);
-    }
-
-    public void add(ModelPerformer performer) {
-        add(new ModelPerformer[]{performer});
-    }
-
-    public void add(ModelInstrument ins, int keyFrom, int keyTo, int velFrom,
-            int velTo, int exclusiveClass) {
-        add(ins.getPerformers(), keyFrom, keyTo, velFrom, velTo, exclusiveClass);
-    }
-
-    public void add(ModelInstrument ins, int keyFrom, int keyTo, int velFrom,
-            int velTo) {
-        add(ins.getPerformers(), keyFrom, keyTo, velFrom, velTo);
-    }
-
-    public void add(ModelInstrument ins, int keyFrom, int keyTo) {
-        add(ins.getPerformers(), keyFrom, keyTo);
-    }
-
-    public void add(ModelInstrument ins) {
-        add(ins.getPerformers());
-    }
-
-    public ModelPerformer[] getPerformers() {
-
-        int percount = 0;
-        for (SimpleInstrumentPart part : parts)
-            if (part.performers != null)
-                percount += part.performers.length;
-
-        ModelPerformer[] performers = new ModelPerformer[percount];
-        int px = 0;
-        for (SimpleInstrumentPart part : parts) {
-            if (part.performers != null) {
-                for (ModelPerformer mperfm : part.performers) {
-                    ModelPerformer performer = new ModelPerformer();
-                    performer.setName(getName());
-                    performers[px++] = performer;
-
-                    performer.setDefaultConnectionsEnabled(
-                            mperfm.isDefaultConnectionsEnabled());
-                    performer.setKeyFrom(mperfm.getKeyFrom());
-                    performer.setKeyTo(mperfm.getKeyTo());
-                    performer.setVelFrom(mperfm.getVelFrom());
-                    performer.setVelTo(mperfm.getVelTo());
-                    performer.setExclusiveClass(mperfm.getExclusiveClass());
-                    performer.setSelfNonExclusive(mperfm.isSelfNonExclusive());
-                    performer.setReleaseTriggered(mperfm.isReleaseTriggered());
-                    if (part.exclusiveClass != -1)
-                        performer.setExclusiveClass(part.exclusiveClass);
-                    if (part.keyFrom > performer.getKeyFrom())
-                        performer.setKeyFrom(part.keyFrom);
-                    if (part.keyTo < performer.getKeyTo())
-                        performer.setKeyTo(part.keyTo);
-                    if (part.velFrom > performer.getVelFrom())
-                        performer.setVelFrom(part.velFrom);
-                    if (part.velTo < performer.getVelTo())
-                        performer.setVelTo(part.velTo);
-                    performer.getOscillators().addAll(mperfm.getOscillators());
-                    performer.getConnectionBlocks().addAll(
-                            mperfm.getConnectionBlocks());
-                }
-            }
-        }
-
-        return performers;
-    }
-
-    public Object getData() {
-        return null;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public ModelPatch getPatch() {
-        return new ModelPatch(bank, preset, percussion);
-    }
-
-    public void setPatch(Patch patch) {
-        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
-            percussion = true;
-            bank = patch.getBank();
-            preset = patch.getProgram();
-        } else {
-            percussion = false;
-            bank = patch.getBank();
-            preset = patch.getProgram();
-        }
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.sound.midi.Patch;
+
+/**
+ * A simple instrument that is made of other ModelInstrument, ModelPerformer
+ * objects.
+ *
+ * @author Karl Helgason
+ */
+public class SimpleInstrument extends ModelInstrument {
+
+    protected class SimpleInstrumentPart {
+        ModelPerformer[] performers;
+        int keyFrom;
+        int keyTo;
+        int velFrom;
+        int velTo;
+        int exclusiveClass;
+    }
+    protected int preset = 0;
+    protected int bank = 0;
+    protected boolean percussion = false;
+    protected String name = "";
+    protected List<SimpleInstrumentPart> parts
+            = new ArrayList<SimpleInstrumentPart>();
+
+    public SimpleInstrument() {
+        super(null, null, null, null);
+    }
+
+    public void clear() {
+        parts.clear();
+    }
+
+    public void add(ModelPerformer[] performers, int keyFrom, int keyTo,
+            int velFrom, int velTo, int exclusiveClass) {
+        SimpleInstrumentPart part = new SimpleInstrumentPart();
+        part.performers = performers;
+        part.keyFrom = keyFrom;
+        part.keyTo = keyTo;
+        part.velFrom = velFrom;
+        part.velTo = velTo;
+        part.exclusiveClass = exclusiveClass;
+        parts.add(part);
+    }
+
+    public void add(ModelPerformer[] performers, int keyFrom, int keyTo,
+            int velFrom, int velTo) {
+        add(performers, keyFrom, keyTo, velFrom, velTo, -1);
+    }
+
+    public void add(ModelPerformer[] performers, int keyFrom, int keyTo) {
+        add(performers, keyFrom, keyTo, 0, 127, -1);
+    }
+
+    public void add(ModelPerformer[] performers) {
+        add(performers, 0, 127, 0, 127, -1);
+    }
+
+    public void add(ModelPerformer performer, int keyFrom, int keyTo,
+            int velFrom, int velTo, int exclusiveClass) {
+        add(new ModelPerformer[]{performer}, keyFrom, keyTo, velFrom, velTo,
+                exclusiveClass);
+    }
+
+    public void add(ModelPerformer performer, int keyFrom, int keyTo,
+            int velFrom, int velTo) {
+        add(new ModelPerformer[]{performer}, keyFrom, keyTo, velFrom, velTo);
+    }
+
+    public void add(ModelPerformer performer, int keyFrom, int keyTo) {
+        add(new ModelPerformer[]{performer}, keyFrom, keyTo);
+    }
+
+    public void add(ModelPerformer performer) {
+        add(new ModelPerformer[]{performer});
+    }
+
+    public void add(ModelInstrument ins, int keyFrom, int keyTo, int velFrom,
+            int velTo, int exclusiveClass) {
+        add(ins.getPerformers(), keyFrom, keyTo, velFrom, velTo, exclusiveClass);
+    }
+
+    public void add(ModelInstrument ins, int keyFrom, int keyTo, int velFrom,
+            int velTo) {
+        add(ins.getPerformers(), keyFrom, keyTo, velFrom, velTo);
+    }
+
+    public void add(ModelInstrument ins, int keyFrom, int keyTo) {
+        add(ins.getPerformers(), keyFrom, keyTo);
+    }
+
+    public void add(ModelInstrument ins) {
+        add(ins.getPerformers());
+    }
+
+    public ModelPerformer[] getPerformers() {
+
+        int percount = 0;
+        for (SimpleInstrumentPart part : parts)
+            if (part.performers != null)
+                percount += part.performers.length;
+
+        ModelPerformer[] performers = new ModelPerformer[percount];
+        int px = 0;
+        for (SimpleInstrumentPart part : parts) {
+            if (part.performers != null) {
+                for (ModelPerformer mperfm : part.performers) {
+                    ModelPerformer performer = new ModelPerformer();
+                    performer.setName(getName());
+                    performers[px++] = performer;
+
+                    performer.setDefaultConnectionsEnabled(
+                            mperfm.isDefaultConnectionsEnabled());
+                    performer.setKeyFrom(mperfm.getKeyFrom());
+                    performer.setKeyTo(mperfm.getKeyTo());
+                    performer.setVelFrom(mperfm.getVelFrom());
+                    performer.setVelTo(mperfm.getVelTo());
+                    performer.setExclusiveClass(mperfm.getExclusiveClass());
+                    performer.setSelfNonExclusive(mperfm.isSelfNonExclusive());
+                    performer.setReleaseTriggered(mperfm.isReleaseTriggered());
+                    if (part.exclusiveClass != -1)
+                        performer.setExclusiveClass(part.exclusiveClass);
+                    if (part.keyFrom > performer.getKeyFrom())
+                        performer.setKeyFrom(part.keyFrom);
+                    if (part.keyTo < performer.getKeyTo())
+                        performer.setKeyTo(part.keyTo);
+                    if (part.velFrom > performer.getVelFrom())
+                        performer.setVelFrom(part.velFrom);
+                    if (part.velTo < performer.getVelTo())
+                        performer.setVelTo(part.velTo);
+                    performer.getOscillators().addAll(mperfm.getOscillators());
+                    performer.getConnectionBlocks().addAll(
+                            mperfm.getConnectionBlocks());
+                }
+            }
+        }
+
+        return performers;
+    }
+
+    public Object getData() {
+        return null;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public ModelPatch getPatch() {
+        return new ModelPatch(bank, preset, percussion);
+    }
+
+    public void setPatch(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch)patch).isPercussion()) {
+            percussion = true;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        } else {
+            percussion = false;
+            bank = patch.getBank();
+            preset = patch.getProgram();
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SimpleSoundbank.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SimpleSoundbank.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,145 +1,145 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.sound.midi.Instrument;
-import javax.sound.midi.Patch;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.SoundbankResource;
-
-/**
- * A simple soundbank that contains instruments and soundbankresources.
- *
- * @author Karl Helgason
- */
-public class SimpleSoundbank implements Soundbank {
-
-    String name = "";
-    String version = "";
-    String vendor = "";
-    String description = "";
-    List<SoundbankResource> resources = new ArrayList<SoundbankResource>();
-    List<Instrument> instruments = new ArrayList<Instrument>();
-
-    public String getName() {
-        return name;
-    }
-
-    public String getVersion() {
-        return version;
-    }
-
-    public String getVendor() {
-        return vendor;
-    }
-
-    public String getDescription() {
-        return description;
-    }
-
-    public void setDescription(String description) {
-        this.description = description;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void setVendor(String vendor) {
-        this.vendor = vendor;
-    }
-
-    public void setVersion(String version) {
-        this.version = version;
-    }
-
-    public SoundbankResource[] getResources() {
-        return resources.toArray(new SoundbankResource[resources.size()]);
-    }
-
-    public Instrument[] getInstruments() {
-        Instrument[] inslist_array
-                = instruments.toArray(new Instrument[resources.size()]);
-        Arrays.sort(inslist_array, new ModelInstrumentComparator());
-        return inslist_array;
-    }
-
-    public Instrument getInstrument(Patch patch) {
-        int program = patch.getProgram();
-        int bank = patch.getBank();
-        boolean percussion = false;
-        if (patch instanceof ModelPatch)
-            percussion = ((ModelPatch)patch).isPercussion();
-        for (Instrument instrument : instruments) {
-            Patch patch2 = instrument.getPatch();
-            int program2 = patch2.getProgram();
-            int bank2 = patch2.getBank();
-            if (program == program2 && bank == bank2) {
-                boolean percussion2 = false;
-                if (patch2 instanceof ModelPatch)
-                    percussion2 = ((ModelPatch)patch2).isPercussion();
-                if (percussion == percussion2)
-                    return instrument;
-            }
-        }
-        return null;
-    }
-
-    public void addResource(SoundbankResource resource) {
-        if (resource instanceof Instrument)
-            instruments.add((Instrument) resource);
-        else
-            resources.add(resource);
-    }
-
-    public void removeResource(SoundbankResource resource) {
-        if (resource instanceof Instrument)
-            instruments.remove((Instrument) resource);
-        else
-            resources.remove(resource);
-    }
-
-    public void addInstrument(Instrument resource) {
-        instruments.add(resource);
-    }
-
-    public void removeInstrument(Instrument resource) {
-        instruments.remove(resource);
-    }
-
-    public void addAllInstruments(Soundbank soundbank) {
-        for (Instrument ins : soundbank.getInstruments())
-            addInstrument(ins);
-    }
-
-    public void removeAllInstruments(Soundbank soundbank) {
-        for (Instrument ins : soundbank.getInstruments())
-            removeInstrument(ins);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.SoundbankResource;
+
+/**
+ * A simple soundbank that contains instruments and soundbankresources.
+ *
+ * @author Karl Helgason
+ */
+public class SimpleSoundbank implements Soundbank {
+
+    String name = "";
+    String version = "";
+    String vendor = "";
+    String description = "";
+    List<SoundbankResource> resources = new ArrayList<SoundbankResource>();
+    List<Instrument> instruments = new ArrayList<Instrument>();
+
+    public String getName() {
+        return name;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public String getVendor() {
+        return vendor;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public void setVendor(String vendor) {
+        this.vendor = vendor;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public SoundbankResource[] getResources() {
+        return resources.toArray(new SoundbankResource[resources.size()]);
+    }
+
+    public Instrument[] getInstruments() {
+        Instrument[] inslist_array
+                = instruments.toArray(new Instrument[resources.size()]);
+        Arrays.sort(inslist_array, new ModelInstrumentComparator());
+        return inslist_array;
+    }
+
+    public Instrument getInstrument(Patch patch) {
+        int program = patch.getProgram();
+        int bank = patch.getBank();
+        boolean percussion = false;
+        if (patch instanceof ModelPatch)
+            percussion = ((ModelPatch)patch).isPercussion();
+        for (Instrument instrument : instruments) {
+            Patch patch2 = instrument.getPatch();
+            int program2 = patch2.getProgram();
+            int bank2 = patch2.getBank();
+            if (program == program2 && bank == bank2) {
+                boolean percussion2 = false;
+                if (patch2 instanceof ModelPatch)
+                    percussion2 = ((ModelPatch)patch2).isPercussion();
+                if (percussion == percussion2)
+                    return instrument;
+            }
+        }
+        return null;
+    }
+
+    public void addResource(SoundbankResource resource) {
+        if (resource instanceof Instrument)
+            instruments.add((Instrument) resource);
+        else
+            resources.add(resource);
+    }
+
+    public void removeResource(SoundbankResource resource) {
+        if (resource instanceof Instrument)
+            instruments.remove((Instrument) resource);
+        else
+            resources.remove(resource);
+    }
+
+    public void addInstrument(Instrument resource) {
+        instruments.add(resource);
+    }
+
+    public void removeInstrument(Instrument resource) {
+        instruments.remove(resource);
+    }
+
+    public void addAllInstruments(Soundbank soundbank) {
+        for (Instrument ins : soundbank.getInstruments())
+            addInstrument(ins);
+    }
+
+    public void removeAllInstruments(Soundbank soundbank) {
+        for (Instrument ins : soundbank.getInstruments())
+            removeInstrument(ins);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftAbstractResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAbstractResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,393 +1,393 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.VoiceStatus;
-
-/**
- * Abstract resampler class.
- *
- * @author Karl Helgason
- */
-public abstract class SoftAbstractResampler implements SoftResampler {
-
-    private class ModelAbstractResamplerStream implements SoftResamplerStreamer {
-
-        AudioFloatInputStream stream;
-        boolean stream_eof = false;
-        int loopmode;
-        boolean loopdirection = true; // true = forward
-        float loopstart;
-        float looplen;
-        float target_pitch;
-        float[] current_pitch = new float[1];
-        boolean started;
-        boolean eof;
-        boolean loopreadevent = false;
-        int sector_pos = 0;
-        int sector_size = 400;
-        int sector_loopstart = -1;
-        boolean markset = false;
-        int marklimit = 0;
-        int streampos = 0;
-        int nrofchannels = 2;
-        boolean noteOff_flag = false;
-        float[][] ibuffer;
-        boolean ibuffer_order = true;
-        float[] sbuffer;
-        int pad;
-        int pad2;
-        float[] ix = new float[1];
-        int[] ox = new int[1];
-        float samplerateconv = 1;
-        float pitchcorrection = 0;
-        boolean streammarked = true;
-
-        public ModelAbstractResamplerStream() {
-            pad = getPadding();
-            pad2 = getPadding() * 2;
-            ibuffer = new float[2][sector_size + pad2];
-            ibuffer_order = true;
-        }
-
-        public void noteOn(MidiChannel channel, VoiceStatus voice,
-                int noteNumber, int velocity) {
-        }
-
-        public void noteOff(int velocity) {
-            noteOff_flag = true;
-        }
-
-        public void open(ModelWavetable osc, float outputsamplerate)
-                throws IOException {
-
-            eof = false;
-            nrofchannels = osc.getChannels();
-            if (ibuffer.length < nrofchannels) {
-                ibuffer = new float[nrofchannels][sector_size + pad2];
-            }
-
-            stream = osc.openStream();
-            streampos = 0;
-            stream_eof = false;
-            pitchcorrection = osc.getPitchcorrection();
-            samplerateconv
-                    = stream.getFormat().getSampleRate() / outputsamplerate;
-            looplen = osc.getLoopLength();
-            loopstart = osc.getLoopStart();
-            sector_loopstart = (int) (loopstart / sector_size);
-            sector_loopstart = sector_loopstart - 1;
-
-            sector_pos = 0;
-
-            if (sector_loopstart < 0)
-                sector_loopstart = 0;
-            started = false;
-            loopmode = osc.getLoopType();
-
-            if (loopmode != 0) {
-                markset = false;
-                marklimit = nrofchannels * (int) (looplen + pad2 + 1);
-            } else
-                markset = true;
-            // loopmode = 0;
-
-            target_pitch = samplerateconv;
-            current_pitch[0] = samplerateconv;
-
-            ibuffer_order = true;
-            loopdirection = true;
-            noteOff_flag = false;
-
-            for (int i = 0; i < nrofchannels; i++)
-                Arrays.fill(ibuffer[i], sector_size, sector_size + pad2, 0);
-            ix[0] = pad;
-            eof = false;
-            loopreadevent = false;
-
-            ix[0] = sector_size + pad;
-            sector_pos = -1;
-            streampos = -sector_size;
-
-            nextBuffer();
-        }
-
-        public void setPitch(float pitch) {
-            /*
-            this.pitch = (float) Math.pow(2f,
-            (pitchcorrection + pitch) / 1200.0f)
-             * samplerateconv;
-             */
-            this.target_pitch = (float)Math.exp(
-                    (pitchcorrection + pitch) * (Math.log(2.0) / 1200.0))
-                * samplerateconv;
-
-            if (!started)
-                current_pitch[0] = this.target_pitch;
-        }
-
-        public void nextBuffer() throws IOException {
-            if (ix[0] < pad) {
-                if (markset) {
-                    // reset to target sector
-                    stream.reset();
-                    ix[0] += streampos - (sector_loopstart * sector_size);
-                    sector_pos = sector_loopstart;
-                    streampos = sector_pos * sector_size;
-
-                    // and go one sector backward
-                    ix[0] += sector_size;
-                    sector_pos -= 1;
-                    streampos -= sector_size;
-                    stream_eof = false;
-                }
-            }
-
-            if (ix[0] >= sector_size + pad) {
-                if (stream_eof) {
-                    eof = true;
-                    return;
-                }
-            }
-
-            if (ix[0] >= sector_size * 4 + pad) {
-                int skips = (int)((ix[0] - sector_size * 4 + pad) / sector_size);
-                ix[0] -= sector_size * skips;
-                sector_pos += skips;
-                streampos += sector_size * skips;
-                stream.skip(sector_size * skips);
-            }
-
-            while (ix[0] >= sector_size + pad) {
-                if (!markset) {
-                    if (sector_pos + 1 == sector_loopstart) {
-                        stream.mark(marklimit);
-                        markset = true;
-                    }
-                }
-                ix[0] -= sector_size;
-                sector_pos++;
-                streampos += sector_size;
-
-                for (int c = 0; c < nrofchannels; c++) {
-                    float[] cbuffer = ibuffer[c];
-                    for (int i = 0; i < pad2; i++)
-                        cbuffer[i] = cbuffer[i + sector_size];
-                }
-
-                int ret;
-                if (nrofchannels == 1)
-                    ret = stream.read(ibuffer[0], pad2, sector_size);
-                else {
-                    int slen = sector_size * nrofchannels;
-                    if (sbuffer == null || sbuffer.length < slen)
-                        sbuffer = new float[slen];
-                    int sret = stream.read(sbuffer, 0, slen);
-                    if (sret == -1)
-                        ret = -1;
-                    else {
-                        ret = sret / nrofchannels;
-                        for (int i = 0; i < nrofchannels; i++) {
-                            float[] buff = ibuffer[i];
-                            int ix = i;
-                            int ix_step = nrofchannels;
-                            int ox = pad2;
-                            for (int j = 0; j < ret; j++, ix += ix_step, ox++)
-                                buff[ox] = sbuffer[ix];
-                        }
-                    }
-
-                }
-
-                if (ret == -1) {
-                    ret = 0;
-                    stream_eof = true;
-                    for (int i = 0; i < nrofchannels; i++)
-                        Arrays.fill(ibuffer[i], pad2, pad2 + sector_size, 0f);
-                    return;
-                }
-                if (ret != sector_size) {
-                    for (int i = 0; i < nrofchannels; i++)
-                        Arrays.fill(ibuffer[i], pad2 + ret, pad2 + sector_size, 0f);
-                }
-
-                ibuffer_order = true;
-
-            }
-
-        }
-
-        public void reverseBuffers() {
-            ibuffer_order = !ibuffer_order;
-            for (int c = 0; c < nrofchannels; c++) {
-                float[] cbuff = ibuffer[c];
-                int len = cbuff.length - 1;
-                int len2 = cbuff.length / 2;
-                for (int i = 0; i < len2; i++) {
-                    float x = cbuff[i];
-                    cbuff[i] = cbuff[len - i];
-                    cbuff[len - i] = x;
-                }
-            }
-        }
-
-        public int read(float[][] buffer, int offset, int len)
-                throws IOException {
-
-            if (eof)
-                return -1;
-
-            if (noteOff_flag)
-                if ((loopmode & 2) != 0)
-                    if (loopdirection)
-                        loopmode = 0;
-
-
-            float pitchstep = (target_pitch - current_pitch[0]) / len;
-            float[] current_pitch = this.current_pitch;
-            started = true;
-
-            int[] ox = this.ox;
-            ox[0] = offset;
-            int ox_end = len + offset;
-
-            float ixend = sector_size + pad;
-            if (!loopdirection)
-                ixend = pad;
-            while (ox[0] != ox_end) {
-                nextBuffer();
-                if (!loopdirection) {
-                    // If we are in backward playing part of pingpong
-                    // or reverse loop
-
-                    if (streampos < (loopstart + pad)) {
-                        ixend = loopstart - streampos + pad2;
-                        if (ix[0] <= ixend) {
-                            if ((loopmode & 4) != 0) {
-                                // Ping pong loop, change loopdirection
-                                loopdirection = true;
-                                ixend = sector_size + pad;
-                                continue;
-                            }
-
-                            ix[0] += looplen;
-                            ixend = pad;
-                            continue;
-                        }
-                    }
-
-                    if (ibuffer_order != loopdirection)
-                        reverseBuffers();
-
-                    ix[0] = (sector_size + pad2) - ix[0];
-                    ixend = (sector_size + pad2) - ixend;
-                    ixend++;
-
-                    float bak_ix = ix[0];
-                    int bak_ox = ox[0];
-                    float bak_pitch = current_pitch[0];
-                    for (int i = 0; i < nrofchannels; i++) {
-                        if (buffer[i] != null) {
-                            ix[0] = bak_ix;
-                            ox[0] = bak_ox;
-                            current_pitch[0] = bak_pitch;
-                            interpolate(ibuffer[i], ix, ixend, current_pitch,
-                                    pitchstep, buffer[i], ox, ox_end);
-                        }
-                    }
-
-                    ix[0] = (sector_size + pad2) - ix[0];
-                    ixend--;
-                    ixend = (sector_size + pad2) - ixend;
-
-                    if (eof) {
-                        current_pitch[0] = this.target_pitch;
-                        return ox[0] - offset;
-                    }
-
-                    continue;
-                }
-                if (loopmode != 0) {
-                    if (streampos + sector_size > (looplen + loopstart + pad)) {
-                        ixend = loopstart + looplen - streampos + pad2;
-                        if (ix[0] >= ixend) {
-                            if ((loopmode & 4) != 0 || (loopmode & 8) != 0) {
-                                // Ping pong or revese loop, change loopdirection
-                                loopdirection = false;
-                                ixend = pad;
-                                continue;
-                            }
-                            ixend = sector_size + pad;
-                            ix[0] -= looplen;
-                            continue;
-                        }
-                    }
-                }
-
-                if (ibuffer_order != loopdirection)
-                    reverseBuffers();
-
-                float bak_ix = ix[0];
-                int bak_ox = ox[0];
-                float bak_pitch = current_pitch[0];
-                for (int i = 0; i < nrofchannels; i++) {
-                    if (buffer[i] != null) {
-                        ix[0] = bak_ix;
-                        ox[0] = bak_ox;
-                        current_pitch[0] = bak_pitch;
-                        interpolate(ibuffer[i], ix, ixend, current_pitch,
-                                pitchstep, buffer[i], ox, ox_end);
-                    }
-                }
-
-                if (eof) {
-                    current_pitch[0] = this.target_pitch;
-                    return ox[0] - offset;
-                }
-            }
-
-            current_pitch[0] = this.target_pitch;
-            return len;
-        }
-
-        public void close() throws IOException {
-            stream.close();
-        }
-    }
-
-    public abstract int getPadding();
-
-    public abstract void interpolate(float[] in, float[] in_offset,
-            float in_end, float[] pitch, float pitchstep, float[] out,
-            int[] out_offset, int out_end);
-
-    public SoftResamplerStreamer openStreamer() {
-        return new ModelAbstractResamplerStream();
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * Abstract resampler class.
+ *
+ * @author Karl Helgason
+ */
+public abstract class SoftAbstractResampler implements SoftResampler {
+
+    private class ModelAbstractResamplerStream implements SoftResamplerStreamer {
+
+        AudioFloatInputStream stream;
+        boolean stream_eof = false;
+        int loopmode;
+        boolean loopdirection = true; // true = forward
+        float loopstart;
+        float looplen;
+        float target_pitch;
+        float[] current_pitch = new float[1];
+        boolean started;
+        boolean eof;
+        boolean loopreadevent = false;
+        int sector_pos = 0;
+        int sector_size = 400;
+        int sector_loopstart = -1;
+        boolean markset = false;
+        int marklimit = 0;
+        int streampos = 0;
+        int nrofchannels = 2;
+        boolean noteOff_flag = false;
+        float[][] ibuffer;
+        boolean ibuffer_order = true;
+        float[] sbuffer;
+        int pad;
+        int pad2;
+        float[] ix = new float[1];
+        int[] ox = new int[1];
+        float samplerateconv = 1;
+        float pitchcorrection = 0;
+        boolean streammarked = true;
+
+        public ModelAbstractResamplerStream() {
+            pad = getPadding();
+            pad2 = getPadding() * 2;
+            ibuffer = new float[2][sector_size + pad2];
+            ibuffer_order = true;
+        }
+
+        public void noteOn(MidiChannel channel, VoiceStatus voice,
+                int noteNumber, int velocity) {
+        }
+
+        public void noteOff(int velocity) {
+            noteOff_flag = true;
+        }
+
+        public void open(ModelWavetable osc, float outputsamplerate)
+                throws IOException {
+
+            eof = false;
+            nrofchannels = osc.getChannels();
+            if (ibuffer.length < nrofchannels) {
+                ibuffer = new float[nrofchannels][sector_size + pad2];
+            }
+
+            stream = osc.openStream();
+            streampos = 0;
+            stream_eof = false;
+            pitchcorrection = osc.getPitchcorrection();
+            samplerateconv
+                    = stream.getFormat().getSampleRate() / outputsamplerate;
+            looplen = osc.getLoopLength();
+            loopstart = osc.getLoopStart();
+            sector_loopstart = (int) (loopstart / sector_size);
+            sector_loopstart = sector_loopstart - 1;
+
+            sector_pos = 0;
+
+            if (sector_loopstart < 0)
+                sector_loopstart = 0;
+            started = false;
+            loopmode = osc.getLoopType();
+
+            if (loopmode != 0) {
+                markset = false;
+                marklimit = nrofchannels * (int) (looplen + pad2 + 1);
+            } else
+                markset = true;
+            // loopmode = 0;
+
+            target_pitch = samplerateconv;
+            current_pitch[0] = samplerateconv;
+
+            ibuffer_order = true;
+            loopdirection = true;
+            noteOff_flag = false;
+
+            for (int i = 0; i < nrofchannels; i++)
+                Arrays.fill(ibuffer[i], sector_size, sector_size + pad2, 0);
+            ix[0] = pad;
+            eof = false;
+            loopreadevent = false;
+
+            ix[0] = sector_size + pad;
+            sector_pos = -1;
+            streampos = -sector_size;
+
+            nextBuffer();
+        }
+
+        public void setPitch(float pitch) {
+            /*
+            this.pitch = (float) Math.pow(2f,
+            (pitchcorrection + pitch) / 1200.0f)
+             * samplerateconv;
+             */
+            this.target_pitch = (float)Math.exp(
+                    (pitchcorrection + pitch) * (Math.log(2.0) / 1200.0))
+                * samplerateconv;
+
+            if (!started)
+                current_pitch[0] = this.target_pitch;
+        }
+
+        public void nextBuffer() throws IOException {
+            if (ix[0] < pad) {
+                if (markset) {
+                    // reset to target sector
+                    stream.reset();
+                    ix[0] += streampos - (sector_loopstart * sector_size);
+                    sector_pos = sector_loopstart;
+                    streampos = sector_pos * sector_size;
+
+                    // and go one sector backward
+                    ix[0] += sector_size;
+                    sector_pos -= 1;
+                    streampos -= sector_size;
+                    stream_eof = false;
+                }
+            }
+
+            if (ix[0] >= sector_size + pad) {
+                if (stream_eof) {
+                    eof = true;
+                    return;
+                }
+            }
+
+            if (ix[0] >= sector_size * 4 + pad) {
+                int skips = (int)((ix[0] - sector_size * 4 + pad) / sector_size);
+                ix[0] -= sector_size * skips;
+                sector_pos += skips;
+                streampos += sector_size * skips;
+                stream.skip(sector_size * skips);
+            }
+
+            while (ix[0] >= sector_size + pad) {
+                if (!markset) {
+                    if (sector_pos + 1 == sector_loopstart) {
+                        stream.mark(marklimit);
+                        markset = true;
+                    }
+                }
+                ix[0] -= sector_size;
+                sector_pos++;
+                streampos += sector_size;
+
+                for (int c = 0; c < nrofchannels; c++) {
+                    float[] cbuffer = ibuffer[c];
+                    for (int i = 0; i < pad2; i++)
+                        cbuffer[i] = cbuffer[i + sector_size];
+                }
+
+                int ret;
+                if (nrofchannels == 1)
+                    ret = stream.read(ibuffer[0], pad2, sector_size);
+                else {
+                    int slen = sector_size * nrofchannels;
+                    if (sbuffer == null || sbuffer.length < slen)
+                        sbuffer = new float[slen];
+                    int sret = stream.read(sbuffer, 0, slen);
+                    if (sret == -1)
+                        ret = -1;
+                    else {
+                        ret = sret / nrofchannels;
+                        for (int i = 0; i < nrofchannels; i++) {
+                            float[] buff = ibuffer[i];
+                            int ix = i;
+                            int ix_step = nrofchannels;
+                            int ox = pad2;
+                            for (int j = 0; j < ret; j++, ix += ix_step, ox++)
+                                buff[ox] = sbuffer[ix];
+                        }
+                    }
+
+                }
+
+                if (ret == -1) {
+                    ret = 0;
+                    stream_eof = true;
+                    for (int i = 0; i < nrofchannels; i++)
+                        Arrays.fill(ibuffer[i], pad2, pad2 + sector_size, 0f);
+                    return;
+                }
+                if (ret != sector_size) {
+                    for (int i = 0; i < nrofchannels; i++)
+                        Arrays.fill(ibuffer[i], pad2 + ret, pad2 + sector_size, 0f);
+                }
+
+                ibuffer_order = true;
+
+            }
+
+        }
+
+        public void reverseBuffers() {
+            ibuffer_order = !ibuffer_order;
+            for (int c = 0; c < nrofchannels; c++) {
+                float[] cbuff = ibuffer[c];
+                int len = cbuff.length - 1;
+                int len2 = cbuff.length / 2;
+                for (int i = 0; i < len2; i++) {
+                    float x = cbuff[i];
+                    cbuff[i] = cbuff[len - i];
+                    cbuff[len - i] = x;
+                }
+            }
+        }
+
+        public int read(float[][] buffer, int offset, int len)
+                throws IOException {
+
+            if (eof)
+                return -1;
+
+            if (noteOff_flag)
+                if ((loopmode & 2) != 0)
+                    if (loopdirection)
+                        loopmode = 0;
+
+
+            float pitchstep = (target_pitch - current_pitch[0]) / len;
+            float[] current_pitch = this.current_pitch;
+            started = true;
+
+            int[] ox = this.ox;
+            ox[0] = offset;
+            int ox_end = len + offset;
+
+            float ixend = sector_size + pad;
+            if (!loopdirection)
+                ixend = pad;
+            while (ox[0] != ox_end) {
+                nextBuffer();
+                if (!loopdirection) {
+                    // If we are in backward playing part of pingpong
+                    // or reverse loop
+
+                    if (streampos < (loopstart + pad)) {
+                        ixend = loopstart - streampos + pad2;
+                        if (ix[0] <= ixend) {
+                            if ((loopmode & 4) != 0) {
+                                // Ping pong loop, change loopdirection
+                                loopdirection = true;
+                                ixend = sector_size + pad;
+                                continue;
+                            }
+
+                            ix[0] += looplen;
+                            ixend = pad;
+                            continue;
+                        }
+                    }
+
+                    if (ibuffer_order != loopdirection)
+                        reverseBuffers();
+
+                    ix[0] = (sector_size + pad2) - ix[0];
+                    ixend = (sector_size + pad2) - ixend;
+                    ixend++;
+
+                    float bak_ix = ix[0];
+                    int bak_ox = ox[0];
+                    float bak_pitch = current_pitch[0];
+                    for (int i = 0; i < nrofchannels; i++) {
+                        if (buffer[i] != null) {
+                            ix[0] = bak_ix;
+                            ox[0] = bak_ox;
+                            current_pitch[0] = bak_pitch;
+                            interpolate(ibuffer[i], ix, ixend, current_pitch,
+                                    pitchstep, buffer[i], ox, ox_end);
+                        }
+                    }
+
+                    ix[0] = (sector_size + pad2) - ix[0];
+                    ixend--;
+                    ixend = (sector_size + pad2) - ixend;
+
+                    if (eof) {
+                        current_pitch[0] = this.target_pitch;
+                        return ox[0] - offset;
+                    }
+
+                    continue;
+                }
+                if (loopmode != 0) {
+                    if (streampos + sector_size > (looplen + loopstart + pad)) {
+                        ixend = loopstart + looplen - streampos + pad2;
+                        if (ix[0] >= ixend) {
+                            if ((loopmode & 4) != 0 || (loopmode & 8) != 0) {
+                                // Ping pong or revese loop, change loopdirection
+                                loopdirection = false;
+                                ixend = pad;
+                                continue;
+                            }
+                            ixend = sector_size + pad;
+                            ix[0] -= looplen;
+                            continue;
+                        }
+                    }
+                }
+
+                if (ibuffer_order != loopdirection)
+                    reverseBuffers();
+
+                float bak_ix = ix[0];
+                int bak_ox = ox[0];
+                float bak_pitch = current_pitch[0];
+                for (int i = 0; i < nrofchannels; i++) {
+                    if (buffer[i] != null) {
+                        ix[0] = bak_ix;
+                        ox[0] = bak_ox;
+                        current_pitch[0] = bak_pitch;
+                        interpolate(ibuffer[i], ix, ixend, current_pitch,
+                                pitchstep, buffer[i], ox, ox_end);
+                    }
+                }
+
+                if (eof) {
+                    current_pitch[0] = this.target_pitch;
+                    return ox[0] - offset;
+                }
+            }
+
+            current_pitch[0] = this.target_pitch;
+            return len;
+        }
+
+        public void close() throws IOException {
+            stream.close();
+        }
+    }
+
+    public abstract int getPadding();
+
+    public abstract void interpolate(float[] in, float[] in_offset,
+            float in_end, float[] pitch, float pitchstep, float[] out,
+            int[] out_offset, int out_end);
+
+    public SoftResamplerStreamer openStreamer() {
+        return new ModelAbstractResamplerStream();
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioBuffer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,104 +1,104 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.Arrays;
-
-import javax.sound.sampled.AudioFormat;
-
-/**
- * This class is used to store audio buffer.
- *
- * @author Karl Helgason
- */
-public class SoftAudioBuffer {
-
-    private int size;
-    private float[] buffer;
-    private boolean empty = true;
-    private AudioFormat format;
-    private AudioFloatConverter converter;
-    private byte[] converter_buffer;
-
-    public SoftAudioBuffer(int size, AudioFormat format) {
-        this.size = size;
-        this.format = format;
-        converter = AudioFloatConverter.getConverter(format);
-    }
-
-    public AudioFormat getFormat() {
-        return format;
-    }
-
-    public int getSize() {
-        return size;
-    }
-
-    public void clear() {
-        if (!empty) {
-            Arrays.fill(buffer, 0);
-            empty = true;
-        }
-    }
-
-    public boolean isSilent() {
-        return empty;
-    }
-
-    public float[] array() {
-        empty = false;
-        if (buffer == null)
-            buffer = new float[size];
-        return buffer;
-    }
-
-    public void get(byte[] buffer, int channel) {
-
-        int framesize_pc = (format.getFrameSize() / format.getChannels());
-        int c_len = size * framesize_pc;
-        if (converter_buffer == null || converter_buffer.length < c_len)
-            converter_buffer = new byte[c_len];
-
-        if (format.getChannels() == 1) {
-            converter.toByteArray(array(), size, buffer);
-        } else {
-            converter.toByteArray(array(), size, converter_buffer);
-            if (channel >= format.getChannels())
-                return;
-            int z_stepover = format.getChannels() * framesize_pc;
-            int k_stepover = framesize_pc;
-            for (int j = 0; j < framesize_pc; j++) {
-                int k = j;
-                int z = channel * framesize_pc + j;
-                for (int i = 0; i < size; i++) {
-                    buffer[z] = converter_buffer[k];
-                    z += z_stepover;
-                    k += k_stepover;
-                }
-            }
-        }
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Arrays;
+
+import javax.sound.sampled.AudioFormat;
+
+/**
+ * This class is used to store audio buffer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftAudioBuffer {
+
+    private int size;
+    private float[] buffer;
+    private boolean empty = true;
+    private AudioFormat format;
+    private AudioFloatConverter converter;
+    private byte[] converter_buffer;
+
+    public SoftAudioBuffer(int size, AudioFormat format) {
+        this.size = size;
+        this.format = format;
+        converter = AudioFloatConverter.getConverter(format);
+    }
+
+    public AudioFormat getFormat() {
+        return format;
+    }
+
+    public int getSize() {
+        return size;
+    }
+
+    public void clear() {
+        if (!empty) {
+            Arrays.fill(buffer, 0);
+            empty = true;
+        }
+    }
+
+    public boolean isSilent() {
+        return empty;
+    }
+
+    public float[] array() {
+        empty = false;
+        if (buffer == null)
+            buffer = new float[size];
+        return buffer;
+    }
+
+    public void get(byte[] buffer, int channel) {
+
+        int framesize_pc = (format.getFrameSize() / format.getChannels());
+        int c_len = size * framesize_pc;
+        if (converter_buffer == null || converter_buffer.length < c_len)
+            converter_buffer = new byte[c_len];
+
+        if (format.getChannels() == 1) {
+            converter.toByteArray(array(), size, buffer);
+        } else {
+            converter.toByteArray(array(), size, converter_buffer);
+            if (channel >= format.getChannels())
+                return;
+            int z_stepover = format.getChannels() * framesize_pc;
+            int k_stepover = framesize_pc;
+            for (int j = 0; j < framesize_pc; j++) {
+                int k = j;
+                int z = channel * framesize_pc + j;
+                for (int i = 0; i < size; i++) {
+                    buffer[z] = converter_buffer[k];
+                    z += z_stepover;
+                    k += k_stepover;
+                }
+            }
+        }
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftAudioProcessor.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioProcessor.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,48 +1,48 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Audio processor interface.
- *
- * @author Karl Helgason
- */
-public interface SoftAudioProcessor {
-
-    public void globalParameterControlChange(int[] slothpath, long param,
-            long value);
-
-    public void init(SoftSynthesizer synthesizer);
-
-    public void setInput(int pin, SoftAudioBuffer input);
-
-    public void setOutput(int pin, SoftAudioBuffer output);
-
-    public void setMixMode(boolean mix);
-
-    public void processAudio();
-
-    public void processControlLogic();
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Audio processor interface.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftAudioProcessor {
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value);
+
+    public void init(SoftSynthesizer synthesizer);
+
+    public void setInput(int pin, SoftAudioBuffer input);
+
+    public void setOutput(int pin, SoftAudioBuffer output);
+
+    public void setMixMode(boolean mix);
+
+    public void processAudio();
+
+    public void processControlLogic();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftAudioPusher.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,95 +1,95 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.SourceDataLine;
-
-/**
- * This is a processor object that writes into SourceDataLine
- *
- * @author Karl Helgason
- */
-public class SoftAudioPusher implements Runnable {
-
-    private volatile boolean active = false;
-    private SourceDataLine sourceDataLine = null;
-    private Thread audiothread;
-    private AudioInputStream ais;
-    private byte[] buffer;
-
-    public SoftAudioPusher(SourceDataLine sourceDataLine, AudioInputStream ais,
-            int workbuffersizer) {
-        this.ais = ais;
-        this.buffer = new byte[workbuffersizer];
-        this.sourceDataLine = sourceDataLine;
-    }
-
-    public synchronized void start() {
-        if (active)
-            return;
-        active = true;
-        audiothread = new Thread(this);
-        audiothread.setPriority(Thread.MAX_PRIORITY);
-        try {
-            Thread.sleep(100);
-        } catch (InterruptedException e) {
-            //e.printStackTrace();
-        }
-        audiothread.start();
-    }
-
-    public synchronized void stop() {
-        if (!active)
-            return;
-        active = false;
-        try {
-            audiothread.join();
-        } catch (InterruptedException e) {
-            //e.printStackTrace();
-        }
-    }
-
-    public void run() {
-        byte[] buffer = SoftAudioPusher.this.buffer;
-        AudioInputStream ais = SoftAudioPusher.this.ais;
-        SourceDataLine sourceDataLine = SoftAudioPusher.this.sourceDataLine;
-
-        try {
-            while (active) {
-                // Read from audio source
-                ais.read(buffer);
-                // Write byte buffer to source output
-                sourceDataLine.write(buffer, 0, buffer.length);
-            }
-        } catch (IOException e) {
-            active = false;
-            //e.printStackTrace();
-        }
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * This is a processor object that writes into SourceDataLine
+ *
+ * @author Karl Helgason
+ */
+public class SoftAudioPusher implements Runnable {
+
+    private volatile boolean active = false;
+    private SourceDataLine sourceDataLine = null;
+    private Thread audiothread;
+    private AudioInputStream ais;
+    private byte[] buffer;
+
+    public SoftAudioPusher(SourceDataLine sourceDataLine, AudioInputStream ais,
+            int workbuffersizer) {
+        this.ais = ais;
+        this.buffer = new byte[workbuffersizer];
+        this.sourceDataLine = sourceDataLine;
+    }
+
+    public synchronized void start() {
+        if (active)
+            return;
+        active = true;
+        audiothread = new Thread(this);
+        audiothread.setPriority(Thread.MAX_PRIORITY);
+        try {
+            Thread.sleep(100);
+        } catch (InterruptedException e) {
+            //e.printStackTrace();
+        }
+        audiothread.start();
+    }
+
+    public synchronized void stop() {
+        if (!active)
+            return;
+        active = false;
+        try {
+            audiothread.join();
+        } catch (InterruptedException e) {
+            //e.printStackTrace();
+        }
+    }
+
+    public void run() {
+        byte[] buffer = SoftAudioPusher.this.buffer;
+        AudioInputStream ais = SoftAudioPusher.this.ais;
+        SourceDataLine sourceDataLine = SoftAudioPusher.this.sourceDataLine;
+
+        try {
+            while (active) {
+                // Read from audio source
+                ais.read(buffer);
+                // Write byte buffer to source output
+                sourceDataLine.write(buffer, 0, buffer.length);
+            }
+        } catch (IOException e) {
+            active = false;
+            //e.printStackTrace();
+        }
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChannel.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,1517 +1,1517 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.Patch;
-
-/**
- * Software Synthesizer MIDI channel class.
- *
- * @author Karl Helgason
- */
-public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
-
-    private static boolean[] dontResetControls = new boolean[128];
-    static {
-        for (int i = 0; i < dontResetControls.length; i++)
-            dontResetControls[i] = false;
-
-        dontResetControls[0] = true;   // Bank Select (MSB)
-        dontResetControls[32] = true;  // Bank Select (LSB)
-        dontResetControls[7] = true;   // Channel Volume (MSB)
-        dontResetControls[8] = true;   // Balance (MSB)
-        dontResetControls[10] = true;  // Pan (MSB)
-        dontResetControls[11] = true;  // Expression (MSB)
-        dontResetControls[91] = true;  // Effects 1 Depth (default: Reverb Send)
-        dontResetControls[92] = true;  // Effects 2 Depth (default: Tremolo Depth)
-        dontResetControls[93] = true;  // Effects 3 Depth (default: Chorus Send)
-        dontResetControls[94] = true;  // Effects 4 Depth (default: Celeste [Detune] Depth)
-        dontResetControls[95] = true;  // Effects 5 Depth (default: Phaser Depth)
-        dontResetControls[70] = true;  // Sound Controller 1 (default: Sound Variation)
-        dontResetControls[71] = true;  // Sound Controller 2 (default: Timbre / Harmonic Quality)
-        dontResetControls[72] = true;  // Sound Controller 3 (default: Release Time)
-        dontResetControls[73] = true;  // Sound Controller 4 (default: Attack Time)
-        dontResetControls[74] = true;  // Sound Controller 5 (default: Brightness)
-        dontResetControls[75] = true;  // Sound Controller 6 (GM2 default: Decay Time)
-        dontResetControls[76] = true;  // Sound Controller 7 (GM2 default: Vibrato Rate)
-        dontResetControls[77] = true;  // Sound Controller 8 (GM2 default: Vibrato Depth)
-        dontResetControls[78] = true;  // Sound Controller 9 (GM2 default: Vibrato Delay)
-        dontResetControls[79] = true;  // Sound Controller 10 (GM2 default: Undefined)
-        dontResetControls[120] = true; // All Sound Off
-        dontResetControls[121] = true; // Reset All Controllers
-        dontResetControls[122] = true; // Local Control On/Off
-        dontResetControls[123] = true; // All Notes Off
-        dontResetControls[124] = true; // Omni Mode Off
-        dontResetControls[125] = true; // Omni Mode On
-        dontResetControls[126] = true; // Poly Mode Off
-        dontResetControls[127] = true; // Poly Mode On
-
-        dontResetControls[6] = true;   // Data Entry (MSB)
-        dontResetControls[38] = true;  // Data Entry (LSB)
-        dontResetControls[96] = true;  // Data Increment
-        dontResetControls[97] = true;  // Data Decrement
-        dontResetControls[98] = true;  // Non-Registered Parameter Number (LSB)
-        dontResetControls[99] = true;  // Non-Registered Parameter Number(MSB)
-        dontResetControls[100] = true; // RPN = Null
-        dontResetControls[101] = true; // RPN = Null
-
-    }
-
-    private static final int RPN_NULL_VALUE = (127 << 7) + 127;
-    private int rpn_control = RPN_NULL_VALUE;
-    private int nrpn_control = RPN_NULL_VALUE;
-    protected double portamento_time = 1; // keyschanges per control buffer time
-    protected int[] portamento_lastnote = new int[128];
-    protected int portamento_lastnote_ix = 0;
-    private int portamento_control_note = -1;
-    private boolean portamento = false;
-    private boolean mono = false;
-    private boolean mute = false;
-    private boolean solo = false;
-    private boolean solomute = false;
-    private Object control_mutex;
-    private int channel;
-    private SoftVoice[] voices;
-    private int bank;
-    private int program;
-    private SoftSynthesizer synthesizer;
-    private SoftMainMixer mainmixer;
-    private int[] polypressure = new int[128];
-    private int channelpressure = 0;
-    private int[] controller = new int[128];
-    private int pitchbend;
-    private double[] co_midi_pitch = new double[1];
-    private double[] co_midi_channel_pressure = new double[1];
-    protected SoftTuning tuning = new SoftTuning();
-    protected int tuning_bank = 0;
-    protected int tuning_program = 0;
-    protected SoftInstrument current_instrument = null;
-    protected ModelChannelMixer current_mixer = null;
-    private ModelDirector current_director = null;
-
-    // Controller Destination Settings
-    protected int cds_control_number = -1;
-    protected ModelConnectionBlock[] cds_control_connections = null;
-    protected ModelConnectionBlock[] cds_channelpressure_connections = null;
-    protected ModelConnectionBlock[] cds_polypressure_connections = null;
-    protected boolean sustain = false;
-    protected boolean[][] keybasedcontroller_active = null;
-    protected double[][] keybasedcontroller_value = null;
-
-    private class MidiControlObject implements SoftControl {
-        double[] pitch = co_midi_pitch;
-        double[] channel_pressure = co_midi_channel_pressure;
-        double[] poly_pressure = new double[1];
-
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            if (name.equals("pitch"))
-                return pitch;
-            if (name.equals("channel_pressure"))
-                return channel_pressure;
-            if (name.equals("poly_pressure"))
-                return poly_pressure;
-            return null;
-        }
-    }
-
-    private SoftControl[] co_midi = new SoftControl[128];
-    {
-        for (int i = 0; i < co_midi.length; i++) {
-            co_midi[i] = new MidiControlObject();
-        }
-    }
-
-    private double[][] co_midi_cc_cc = new double[128][1];
-    private SoftControl co_midi_cc = new SoftControl() {
-        double[][] cc = co_midi_cc_cc;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            return cc[Integer.parseInt(name)];
-        }
-    };
-    Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<Integer, int[]>();
-    Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<Integer, double[]>();
-    private SoftControl co_midi_rpn = new SoftControl() {
-        Map<Integer, double[]> rpn = co_midi_rpn_rpn;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            int iname = Integer.parseInt(name);
-            double[] v = rpn.get(iname);
-            if (v == null) {
-                v = new double[1];
-                rpn.put(iname, v);
-            }
-            return v;
-        }
-    };
-    Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<Integer, int[]>();
-    Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<Integer, double[]>();
-    private SoftControl co_midi_nrpn = new SoftControl() {
-        Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            int iname = Integer.parseInt(name);
-            double[] v = nrpn.get(iname);
-            if (v == null) {
-                v = new double[1];
-                nrpn.put(iname, v);
-            }
-            return v;
-        }
-    };
-
-    public SoftChannel(SoftSynthesizer synth, int channel) {
-        this.channel = channel;
-        this.voices = synth.getVoices();
-        this.synthesizer = synth;
-        this.mainmixer = synth.getMainMixer();
-        control_mutex = synth.control_mutex;
-        resetAllControllers(true);
-    }
-
-    private int findFreeVoice(int x) {
-        for (int i = x; i < voices.length; i++)
-            if (!voices[i].active)
-                return i;
-
-        // No free voice was found, we must steal one
-
-        int vmode = synthesizer.getVoiceAllocationMode();
-        if (vmode == 1) {
-            // DLS Static Voice Allocation
-
-            //  * priority ( 10, 1-9, 11-16)
-            // Search for channel to steal from
-            int steal_channel = channel;
-            for (int j = 0; j < voices.length; j++) {
-                if (voices[j].stealer_channel == null) {
-                    if (steal_channel == 9) {
-                        steal_channel = voices[j].channel;
-                    } else {
-                        if (voices[j].channel != 9) {
-                            if (voices[j].channel > steal_channel)
-                                steal_channel = voices[j].channel;
-                        }
-                    }
-                }
-            }
-
-            int voiceNo = -1;
-
-            SoftVoice v = null;
-            // Search for oldest voice in off state on steal_channel
-            for (int j = 0; j < voices.length; j++) {
-                if (voices[j].channel == steal_channel) {
-                    if (voices[j].stealer_channel == null && !voices[j].on) {
-                        if (v == null) {
-                            v = voices[j];
-                            voiceNo = j;
-                        }
-                        if (voices[j].voiceID < v.voiceID) {
-                            v = voices[j];
-                            voiceNo = j;
-                        }
-                    }
-                }
-            }
-            // Search for oldest voice in on state on steal_channel
-            if (voiceNo == -1) {
-                for (int j = 0; j < voices.length; j++) {
-                    if (voices[j].channel == steal_channel) {
-                        if (voices[j].stealer_channel == null) {
-                            if (v == null) {
-                                v = voices[j];
-                                voiceNo = j;
-                            }
-                            if (voices[j].voiceID < v.voiceID) {
-                                v = voices[j];
-                                voiceNo = j;
-                            }
-                        }
-                    }
-                }
-            }
-
-            return voiceNo;
-
-        } else {
-            // Default Voice Allocation
-            //  * Find voice that is on
-            //  	and Find voice which has lowest voiceID ( oldest voice)
-            //  * Or find voice that is off
-            //  	and Find voice which has lowest voiceID ( oldest voice)
-
-            int voiceNo = -1;
-
-            SoftVoice v = null;
-            // Search for oldest voice in off state
-            for (int j = 0; j < voices.length; j++) {
-                if (voices[j].stealer_channel == null && !voices[j].on) {
-                    if (v == null) {
-                        v = voices[j];
-                        voiceNo = j;
-                    }
-                    if (voices[j].voiceID < v.voiceID) {
-                        v = voices[j];
-                        voiceNo = j;
-                    }
-                }
-            }
-            // Search for oldest voice in on state
-            if (voiceNo == -1) {
-
-                for (int j = 0; j < voices.length; j++) {
-                    if (voices[j].stealer_channel == null) {
-                        if (v == null) {
-                            v = voices[j];
-                            voiceNo = j;
-                        }
-                        if (voices[j].voiceID < v.voiceID) {
-                            v = voices[j];
-                            voiceNo = j;
-                        }
-                    }
-                }
-            }
-
-            return voiceNo;
-        }
-
-    }
-
-    protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID,
-            int noteNumber, int velocity, ModelConnectionBlock[] connectionBlocks,
-            ModelChannelMixer channelmixer, boolean releaseTriggered) {
-        if (voice.active) {
-            // Voice is active , we must steal the voice
-            voice.stealer_channel = this;
-            voice.stealer_performer = p;
-            voice.stealer_voiceID = voiceID;
-            voice.stealer_noteNumber = noteNumber;
-            voice.stealer_velocity = velocity;
-            voice.stealer_extendedConnectionBlocks = connectionBlocks;
-            voice.stealer_channelmixer = channelmixer;
-            voice.stealer_releaseTriggered = releaseTriggered;
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active && voices[i].voiceID == voice.voiceID)
-                    voices[i].soundOff();
-            return;
-        }
-
-        voice.extendedConnectionBlocks = connectionBlocks;
-        voice.channelmixer = channelmixer;
-        voice.releaseTriggered = releaseTriggered;
-        voice.voiceID = voiceID;
-        voice.tuning = tuning;
-        voice.exclusiveClass = p.exclusiveClass;
-        voice.softchannel = this;
-        voice.channel = channel;
-        voice.bank = bank;
-        voice.program = program;
-        voice.instrument = current_instrument;
-        voice.performer = p;
-        voice.objects.clear();
-        voice.objects.put("midi", co_midi[noteNumber]);
-        voice.objects.put("midi_cc", co_midi_cc);
-        voice.objects.put("midi_rpn", co_midi_rpn);
-        voice.objects.put("midi_nrpn", co_midi_nrpn);
-        voice.noteOn(noteNumber, velocity);
-        voice.setMute(mute);
-        voice.setSoloMute(solomute);
-        if (releaseTriggered)
-            return;
-        if (portamento_control_note != -1) {
-            voice.co_noteon_keynumber[0]
-                    = (tuning.getTuning(portamento_control_note) / 100.0)
-                    * (1f / 128f);
-            voice.portamento = true;
-            portamento_control_note = -1;
-        } else if (portamento) {
-            if (mono) {
-                if (portamento_lastnote[0] != -1) {
-                    voice.co_noteon_keynumber[0]
-                            = (tuning.getTuning(portamento_lastnote[0]) / 100.0)
-                            * (1f / 128f);
-                    voice.portamento = true;
-                    portamento_control_note = -1;
-                }
-                portamento_lastnote[0] = noteNumber;
-            } else {
-                if (portamento_lastnote_ix != 0) {
-                    portamento_lastnote_ix--;
-                    voice.co_noteon_keynumber[0]
-                            = (tuning.getTuning(
-                                    portamento_lastnote[portamento_lastnote_ix])
-                                / 100.0)
-                            * (1f / 128f);
-                    voice.portamento = true;
-                }
-            }
-        }
-    }
-
-    public void noteOn(int noteNumber, int velocity) {
-
-        noteOn_internal(noteNumber, velocity);
-        if (current_mixer != null)
-            current_mixer.noteOn(noteNumber, velocity);
-    }
-
-    private void noteOn_internal(int noteNumber, int velocity) {
-
-        if (velocity == 0) {
-            noteOff_internal(noteNumber, 64);
-            return;
-        }
-
-        synchronized (control_mutex) {
-            if (sustain) {
-                sustain = false;
-                for (int i = 0; i < voices.length; i++) {
-                    if ((voices[i].sustain || voices[i].on)
-                            && voices[i].channel == channel && voices[i].active
-                            && voices[i].note == noteNumber) {
-                        voices[i].sustain = false;
-                        voices[i].on = true;
-                        voices[i].noteOff(0);
-                    }
-                }
-                sustain = true;
-            }
-
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-
-            if (mono) {
-                if (portamento) {
-                    boolean n_found = false;
-                    for (int i = 0; i < voices.length; i++) {
-                        if (voices[i].on && voices[i].channel == channel
-                                && voices[i].active
-                                && voices[i].releaseTriggered == false) {
-                            voices[i].portamento = true;
-                            voices[i].setNote(noteNumber);
-                            n_found = true;
-                        }
-                    }
-                    if (n_found) {
-                        portamento_lastnote[0] = noteNumber;
-                        return;
-                    }
-                }
-
-                if (portamento_control_note != -1) {
-                    boolean n_found = false;
-                    for (int i = 0; i < voices.length; i++) {
-                        if (voices[i].on && voices[i].channel == channel
-                                && voices[i].active
-                                && voices[i].note == portamento_control_note
-                                && voices[i].releaseTriggered == false) {
-                            voices[i].portamento = true;
-                            voices[i].setNote(noteNumber);
-                            n_found = true;
-                        }
-                    }
-                    portamento_control_note = -1;
-                    if (n_found)
-                        return;
-                }
-            }
-
-            if (mono)
-                allNotesOff();
-
-            if (current_instrument == null) {
-                current_instrument
-                        = synthesizer.findInstrument(program, bank, channel);
-                if (current_instrument == null)
-                    return;
-                if (current_mixer != null)
-                    mainmixer.stopMixer(current_mixer);
-                current_mixer = current_instrument.getSourceInstrument()
-                        .getChannelMixer(this, synthesizer.getFormat());
-                if (current_mixer != null)
-                    mainmixer.registerMixer(current_mixer);
-                current_director = current_instrument.getDirector(this, this);
-                applyInstrumentCustomization();
-            }
-            prevVoiceID = synthesizer.voiceIDCounter++;
-            firstVoice = true;
-            voiceNo = 0;
-
-            int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
-            play_noteNumber = noteNumber;
-            play_velocity = velocity;
-            play_releasetriggered = false;
-            lastVelocity[noteNumber] = velocity;
-            current_director.noteOn(tunedKey, velocity);
-
-            /*
-            SoftPerformer[] performers = current_instrument.getPerformers();
-            for (int i = 0; i < performers.length; i++) {
-                SoftPerformer p = performers[i];
-                if (p.keyFrom <= tunedKey && p.keyTo >= tunedKey) {
-                    if (p.velFrom <= velocity && p.velTo >= velocity) {
-                        if (firstVoice) {
-                            firstVoice = false;
-                            if (p.exclusiveClass != 0) {
-                                int x = p.exclusiveClass;
-                                for (int j = 0; j < voices.length; j++) {
-                                    if (voices[j].active
-                                            && voices[j].channel == channel
-                                            && voices[j].exclusiveClass == x) {
-                                        if (!(p.selfNonExclusive
-                                                && voices[j].note == noteNumber))
-                                            voices[j].shutdown();
-                                    }
-                                }
-                            }
-                        }
-                        voiceNo = findFreeVoice(voiceNo);
-                        if (voiceNo == -1)
-                            return;
-                        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber,
-                                velocity);
-                    }
-                }
-            }
-            */
-        }
-    }
-
-    public void noteOff(int noteNumber, int velocity) {
-        noteOff_internal(noteNumber, velocity);
-
-        if (current_mixer != null)
-            current_mixer.noteOff(noteNumber, velocity);
-    }
-
-    private void noteOff_internal(int noteNumber, int velocity) {
-        synchronized (control_mutex) {
-
-            if (!mono) {
-                if (portamento) {
-                    if (portamento_lastnote_ix != 127) {
-                        portamento_lastnote[portamento_lastnote_ix] = noteNumber;
-                        portamento_lastnote_ix++;
-                    }
-                }
-            }
-
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-            for (int i = 0; i < voices.length; i++) {
-                if (voices[i].on && voices[i].channel == channel
-                        && voices[i].note == noteNumber
-                        && voices[i].releaseTriggered == false) {
-                    voices[i].noteOff(velocity);
-                }
-            }
-
-            // Try play back note-off triggered voices,
-
-            if (current_instrument == null) {
-                current_instrument
-                        = synthesizer.findInstrument(program, bank, channel);
-                if (current_instrument == null)
-                    return;
-                if (current_mixer != null)
-                    mainmixer.stopMixer(current_mixer);
-                current_mixer = current_instrument.getSourceInstrument()
-                        .getChannelMixer(this, synthesizer.getFormat());
-                if (current_mixer != null)
-                    mainmixer.registerMixer(current_mixer);
-                current_director = current_instrument.getDirector(this, this);
-                applyInstrumentCustomization();
-
-            }
-            prevVoiceID = synthesizer.voiceIDCounter++;
-            firstVoice = true;
-            voiceNo = 0;
-
-            int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
-            play_noteNumber = noteNumber;
-            play_velocity = lastVelocity[noteNumber];
-            play_releasetriggered = true;
-            current_director.noteOff(tunedKey, velocity);
-
-        }
-    }
-    private int[] lastVelocity = new int[128];
-    private int prevVoiceID;
-    private boolean firstVoice = true;
-    private int voiceNo = 0;
-    private int play_noteNumber = 0;
-    private int play_velocity = 0;
-    private boolean play_releasetriggered = false;
-
-    public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) {
-
-        int noteNumber = play_noteNumber;
-        int velocity = play_velocity;
-        boolean releasetriggered = play_releasetriggered;
-
-        SoftPerformer p = current_instrument.getPerformers()[performerIndex];
-
-        if (firstVoice) {
-            firstVoice = false;
-            if (p.exclusiveClass != 0) {
-                int x = p.exclusiveClass;
-                for (int j = 0; j < voices.length; j++) {
-                    if (voices[j].active && voices[j].channel == channel
-                            && voices[j].exclusiveClass == x) {
-                        if (!(p.selfNonExclusive && voices[j].note == noteNumber))
-                            voices[j].shutdown();
-                    }
-                }
-            }
-        }
-
-        voiceNo = findFreeVoice(voiceNo);
-
-        if (voiceNo == -1)
-            return;
-
-        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity,
-                connectionBlocks, current_mixer, releasetriggered);
-    }
-
-    public void noteOff(int noteNumber) {
-        noteOff_internal(noteNumber, 64);
-    }
-
-    public void setPolyPressure(int noteNumber, int pressure) {
-        if (current_mixer != null)
-            current_mixer.setPolyPressure(noteNumber, pressure);
-
-        synchronized (control_mutex) {
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-            co_midi[noteNumber].get(0, "poly_pressure")[0] = pressure*(1.0/128.0);
-            polypressure[noteNumber] = pressure;
-            for (int i = 0; i < voices.length; i++) {
-                if (voices[i].active && voices[i].note == noteNumber)
-                    voices[i].setPolyPressure(pressure);
-            }
-        }
-    }
-
-    public int getPolyPressure(int noteNumber) {
-        synchronized (control_mutex) {
-            return polypressure[noteNumber];
-        }
-    }
-
-    public void setChannelPressure(int pressure) {
-        if (current_mixer != null)
-            current_mixer.setChannelPressure(pressure);
-        synchronized (control_mutex) {
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-            co_midi_channel_pressure[0] = pressure * (1.0 / 128.0);
-            channelpressure = pressure;
-            for (int i = 0; i < voices.length; i++) {
-                if (voices[i].active)
-                    voices[i].setChannelPressure(pressure);
-            }
-        }
-    }
-
-    public int getChannelPressure() {
-        synchronized (control_mutex) {
-            return channelpressure;
-        }
-    }
-
-    protected void applyInstrumentCustomization() {
-        if (cds_control_connections == null
-                && cds_channelpressure_connections == null
-                && cds_polypressure_connections == null) {
-            return;
-        }
-
-        ModelInstrument src_instrument = current_instrument.getSourceInstrument();
-        ModelPerformer[] performers = src_instrument.getPerformers();
-        ModelPerformer[] new_performers = new ModelPerformer[performers.length];
-        for (int i = 0; i < new_performers.length; i++) {
-            ModelPerformer performer = performers[i];
-            ModelPerformer new_performer = new ModelPerformer();
-            new_performer.setName(performer.getName());
-            new_performer.setExclusiveClass(performer.getExclusiveClass());
-            new_performer.setKeyFrom(performer.getKeyFrom());
-            new_performer.setKeyTo(performer.getKeyTo());
-            new_performer.setVelFrom(performer.getVelFrom());
-            new_performer.setVelTo(performer.getVelTo());
-            new_performer.getOscillators().addAll(performer.getOscillators());
-            new_performer.getConnectionBlocks().addAll(
-                    performer.getConnectionBlocks());
-            new_performers[i] = new_performer;
-
-            List<ModelConnectionBlock> connblocks =
-                    new_performer.getConnectionBlocks();
-
-            if (cds_control_connections != null) {
-                String cc = Integer.toString(cds_control_number);
-                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
-                while (iter.hasNext()) {
-                    ModelConnectionBlock conn = iter.next();
-                    ModelSource[] sources = conn.getSources();
-                    boolean removeok = false;
-                    if (sources != null) {
-                        for (int j = 0; j < sources.length; j++) {
-                            ModelSource src = sources[j];
-                            if ("midi_cc".equals(src.getIdentifier().getObject())
-                                    && cc.equals(src.getIdentifier().getVariable())) {
-                                removeok = true;
-                            }
-                        }
-                    }
-                    if (removeok)
-                        iter.remove();
-                }
-                for (int j = 0; j < cds_control_connections.length; j++)
-                    connblocks.add(cds_control_connections[j]);
-            }
-
-            if (cds_polypressure_connections != null) {
-                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
-                while (iter.hasNext()) {
-                    ModelConnectionBlock conn = iter.next();
-                    ModelSource[] sources = conn.getSources();
-                    boolean removeok = false;
-                    if (sources != null) {
-                        for (int j = 0; j < sources.length; j++) {
-                            ModelSource src = sources[j];
-                            if ("midi".equals(src.getIdentifier().getObject())
-                                    && "poly_pressure".equals(
-                                        src.getIdentifier().getVariable())) {
-                                removeok = true;
-                            }
-                        }
-                    }
-                    if (removeok)
-                        iter.remove();
-                }
-                for (int j = 0; j < cds_polypressure_connections.length; j++)
-                    connblocks.add(cds_polypressure_connections[j]);
-            }
-
-
-            if (cds_channelpressure_connections != null) {
-                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
-                while (iter.hasNext()) {
-                    ModelConnectionBlock conn = iter.next();
-                    ModelSource[] sources = conn.getSources();
-                    boolean removeok = false;
-                    if (sources != null) {
-                        for (int j = 0; j < sources.length; j++) {
-                            ModelIdentifier srcid = sources[j].getIdentifier();
-                            if ("midi".equals(srcid.getObject()) &&
-                                    "channel_pressure".equals(srcid.getVariable())) {
-                                removeok = true;
-                            }
-                        }
-                    }
-                    if (removeok)
-                        iter.remove();
-                }
-                for (int j = 0; j < cds_channelpressure_connections.length; j++)
-                    connblocks.add(cds_channelpressure_connections[j]);
-            }
-
-        }
-
-        current_instrument = new SoftInstrument(src_instrument, new_performers);
-
-    }
-
-    private ModelConnectionBlock[] createModelConnections(ModelIdentifier sid,
-            int[] destination, int[] range) {
-
-        /*
-        controlled parameter (pp)|range (rr)| Description             |Default
-        -------------------------|----------|-------------------------|-------
-        00 Pitch Control         | 28H..58H | -24..+24 semitones      | 40H
-        01 Filter Cutoff Control | 00H..7FH | -9600..+9450 cents      | 40H
-        02 Amplitude Control     | 00H..7FH | 0..(127/64)*100 percent | 40H
-        03 LFO Pitch Depth       | 00H..7FH | 0..600 cents            |  0
-        04 LFO Filter Depth      | 00H..7FH | 0..2400 cents           |  0
-        05 LFO Amplitude Depth   | 00H..7FH | 0..100 percent          |  0
-        */
-
-        List<ModelConnectionBlock> conns = new ArrayList<ModelConnectionBlock>();
-
-        for (int i = 0; i < destination.length; i++) {
-            int d = destination[i];
-            int r = range[i];
-            if (d == 0) {
-                double scale = (r - 64) * 100;
-                ModelConnectionBlock conn = new ModelConnectionBlock(
-                        new ModelSource(sid,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_UNIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        scale,
-                        new ModelDestination(
-                            new ModelIdentifier("osc", "pitch")));
-                conns.add(conn);
-
-            }
-            if (d == 1) {
-                double scale = (r / 64.0 - 1.0) * 9600.0;
-                ModelConnectionBlock conn;
-                if (scale > 0) {
-                    conn = new ModelConnectionBlock(
-                            new ModelSource(sid,
-                                ModelStandardTransform.DIRECTION_MAX2MIN,
-                                ModelStandardTransform.POLARITY_UNIPOLAR,
-                                ModelStandardTransform.TRANSFORM_LINEAR),
-                            -scale,
-                            new ModelDestination(
-                                ModelDestination.DESTINATION_FILTER_FREQ));
-                } else {
-                    conn = new ModelConnectionBlock(
-                            new ModelSource(sid,
-                                ModelStandardTransform.DIRECTION_MIN2MAX,
-                                ModelStandardTransform.POLARITY_UNIPOLAR,
-                                ModelStandardTransform.TRANSFORM_LINEAR),
-                            scale,
-                            new ModelDestination(
-                                ModelDestination.DESTINATION_FILTER_FREQ));
-                }
-                conns.add(conn);
-            }
-            if (d == 2) {
-                final double scale = (r / 64.0);
-                ModelTransform mt = new ModelTransform() {
-                    double s = scale;
-                    public double transform(double value) {
-                        if (s < 1)
-                            value = s + (value * (1.0 - s));
-                        else if (s > 1)
-                            value = 1 + (value * (s - 1.0));
-                        else
-                            return 0;
-                        return -((5.0 / 12.0) / Math.log(10)) * Math.log(value);
-                    }
-                };
-
-                ModelConnectionBlock conn = new ModelConnectionBlock(
-                        new ModelSource(sid, mt), -960,
-                        new ModelDestination(ModelDestination.DESTINATION_GAIN));
-                conns.add(conn);
-
-            }
-            if (d == 3) {
-                double scale = (r / 64.0 - 1.0) * 9600.0;
-                ModelConnectionBlock conn = new ModelConnectionBlock(
-                        new ModelSource(ModelSource.SOURCE_LFO1,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_BIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        new ModelSource(sid,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_UNIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        scale,
-                        new ModelDestination(
-                            ModelDestination.DESTINATION_PITCH));
-                conns.add(conn);
-            }
-            if (d == 4) {
-                double scale = (r / 128.0) * 2400.0;
-                ModelConnectionBlock conn = new ModelConnectionBlock(
-                        new ModelSource(ModelSource.SOURCE_LFO1,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_BIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        new ModelSource(sid,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_UNIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        scale,
-                        new ModelDestination(
-                            ModelDestination.DESTINATION_FILTER_FREQ));
-                conns.add(conn);
-            }
-            if (d == 5) {
-                final double scale = (r / 127.0);
-
-                ModelTransform mt = new ModelTransform() {
-                    double s = scale;
-                    public double transform(double value) {
-                        return -((5.0 / 12.0) / Math.log(10))
-                                * Math.log(1 - value * s);
-                    }
-                };
-
-                ModelConnectionBlock conn = new ModelConnectionBlock(
-                        new ModelSource(ModelSource.SOURCE_LFO1,
-                            ModelStandardTransform.DIRECTION_MIN2MAX,
-                            ModelStandardTransform.POLARITY_UNIPOLAR,
-                            ModelStandardTransform.TRANSFORM_LINEAR),
-                        new ModelSource(sid, mt),
-                        -960,
-                        new ModelDestination(
-                            ModelDestination.DESTINATION_GAIN));
-                conns.add(conn);
-            }
-        }
-
-        return conns.toArray(new ModelConnectionBlock[conns.size()]);
-    }
-
-    public void mapPolyPressureToDestination(int[] destination, int[] range) {
-        current_instrument = null;
-        if (destination.length == 0) {
-            cds_polypressure_connections = null;
-            return;
-        }
-        cds_polypressure_connections
-                = createModelConnections(
-                    new ModelIdentifier("midi", "poly_pressure"),
-                    destination, range);
-    }
-
-    public void mapChannelPressureToDestination(int[] destination, int[] range) {
-        current_instrument = null;
-        if (destination.length == 0) {
-            cds_channelpressure_connections = null;
-            return;
-        }
-        cds_channelpressure_connections
-                = createModelConnections(
-                    new ModelIdentifier("midi", "channel_pressure"),
-                    destination, range);
-    }
-
-    public void mapControlToDestination(int control, int[] destination, int[] range) {
-
-        if (!((control >= 0x01 && control <= 0x1F)
-                || (control >= 0x40 && control <= 0x5F))) {
-            cds_control_connections = null;
-            return;
-        }
-
-        current_instrument = null;
-        cds_control_number = control;
-        if (destination.length == 0) {
-            cds_control_connections = null;
-            return;
-        }
-        cds_control_connections
-                = createModelConnections(
-                    new ModelIdentifier("midi_cc", Integer.toString(control)),
-                    destination, range);
-    }
-
-    public void controlChangePerNote(int noteNumber, int controller, int value) {
-
-/*
- CC# | nn   | Name                    | vv             | default    | description
------|------|-------------------------|----------------|------------|-------------------------------
-7    |07H   |Note Volume              |00H-40H-7FH     |40H         |0-100-(127/64)*100(%)(Relative)
-10   |0AH   |*Pan                     |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
-33-63|21-3FH|LSB for                  |01H-1FH         |            |
-71   |47H   |Timbre/Harmonic Intensity|00H-40H-7FH     |40H (???)   |
-72   |48H   |Release Time             |00H-40H-7FH     |40H (???)   |
-73   |49H   |Attack Time              |00H-40H-7FH     |40H (???)   |
-74   |4AH   |Brightness               |00H-40H-7FH     |40H (???)   |
-75   |4BH   |Decay Time               |00H-40H-7FH     |40H (???)   |
-76   |4CH   |Vibrato Rate             |00H-40H-7FH     |40H (???)   |
-77   |4DH   |Vibrato Depth            |00H-40H-7FH     |40H (???)   |
-78   |4EH   |Vibrato Delay            |00H-40H-7FH     |40H (???)   |
-91   |5BH   |*Reverb Send             |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
-93   |5DH   |*Chorus Send             |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
-120  |78H   |**Fine Tuning            |00H-40H-7FH     |40H (???)   |
-121  |79H   |**Coarse Tuning          |00H-40H-7FH     |40H (???)   |
-*/
-
-        if (keybasedcontroller_active == null) {
-            keybasedcontroller_active = new boolean[128][];
-            keybasedcontroller_value = new double[128][];
-        }
-        if (keybasedcontroller_active[noteNumber] == null) {
-            keybasedcontroller_active[noteNumber] = new boolean[128];
-            Arrays.fill(keybasedcontroller_active[noteNumber], false);
-            keybasedcontroller_value[noteNumber] = new double[128];
-            Arrays.fill(keybasedcontroller_value[noteNumber], 0);
-        }
-
-        if (value == -1) {
-            keybasedcontroller_active[noteNumber][controller] = false;
-        } else {
-            keybasedcontroller_active[noteNumber][controller] = true;
-            keybasedcontroller_value[noteNumber][controller] = value / 128.0;
-        }
-
-        if (controller < 120) {
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active)
-                    voices[i].controlChange(controller, -1);
-        } else if (controller == 120) {
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active)
-                    voices[i].rpnChange(1, -1);
-        } else if (controller == 121) {
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active)
-                    voices[i].rpnChange(2, -1);
-        }
-
-    }
-
-    public int getControlPerNote(int noteNumber, int controller) {
-        if (keybasedcontroller_active == null)
-            return -1;
-        if (keybasedcontroller_active[noteNumber] == null)
-            return -1;
-        if (!keybasedcontroller_active[noteNumber][controller])
-            return -1;
-        return (int)(keybasedcontroller_value[noteNumber][controller] * 128);
-    }
-
-    public void controlChange(int controller, int value) {
-        if (current_mixer != null)
-            current_mixer.controlChange(controller, value);
-
-        synchronized (control_mutex) {
-            switch (controller) {
-            /*
-            Map<String, int[]>co_midi_rpn_rpn_i = new HashMap<String, int[]>();
-            Map<String, double[]>co_midi_rpn_rpn = new HashMap<String, double[]>();
-            Map<String, int[]>co_midi_nrpn_nrpn_i = new HashMap<String, int[]>();
-            Map<String, double[]>co_midi_nrpn_nrpn = new HashMap<String, double[]>();
-             */
-
-            case 5:
-                // This produce asin-like curve
-                // as described in General Midi Level 2 Specification, page 6
-                double x = -Math.asin((value / 128.0) * 2 - 1) / Math.PI + 0.5;
-                x = Math.pow(100000.0, x) / 100.0;  // x is now cent/msec
-                // Convert x from cent/msec to key/controlbuffertime
-                x = x / 100.0;                      // x is now keys/msec
-                x = x * 1000.0;                     // x is now keys/sec
-                x = x / synthesizer.getControlRate(); // x is now keys/controlbuffertime
-                portamento_time = x;
-                break;
-            case 6:
-            case 38:
-            case 96:
-            case 97:
-                int val = 0;
-                if (nrpn_control != RPN_NULL_VALUE) {
-                    int[] val_i = co_midi_nrpn_nrpn_i.get(nrpn_control);
-                    if (val_i != null)
-                        val = val_i[0];
-                }
-                if (rpn_control != RPN_NULL_VALUE) {
-                    int[] val_i = co_midi_rpn_rpn_i.get(rpn_control);
-                    if (val_i != null)
-                        val = val_i[0];
-                }
-
-                if (controller == 6)
-                    val = (val & 127) + (value << 7);
-                else if (controller == 38)
-                    val = (val & (127 << 7)) + value;
-                else if (controller == 96 || controller == 97) {
-                    int step = 1;
-                    if (rpn_control == 2 || rpn_control == 3 || rpn_control == 4)
-                        step = 128;
-                    if (controller == 96)
-                        val += step;
-                    if (controller == 97)
-                        val -= step;
-                }
-
-                if (nrpn_control != RPN_NULL_VALUE)
-                    nrpnChange(nrpn_control, val);
-                if (rpn_control != RPN_NULL_VALUE)
-                    rpnChange(rpn_control, val);
-
-                break;
-            case 64: // Hold1 (Damper) (cc#64)
-                boolean on = value >= 64;
-                if (sustain != on) {
-                    sustain = on;
-                    if (!on) {
-                        for (int i = 0; i < voices.length; i++) {
-                            if (voices[i].active && voices[i].sustain &&
-                                    voices[i].channel == channel) {
-                                voices[i].sustain = false;
-                                if (!voices[i].on) {
-                                    voices[i].on = true;
-                                    voices[i].noteOff(0);
-                                }
-                            }
-                        }
-                    } else {
-                        for (int i = 0; i < voices.length; i++)
-                            if (voices[i].active && voices[i].channel == channel)
-                                voices[i].redamp();
-                    }
-                }
-                break;
-            case 65:
-                //allNotesOff();
-                portamento = value >= 64;
-                portamento_lastnote[0] = -1;
-                /*
-                for (int i = 0; i < portamento_lastnote.length; i++)
-                    portamento_lastnote[i] = -1;
-                 */
-                portamento_lastnote_ix = 0;
-                break;
-            case 66: // Sostenuto (cc#66)
-                on = value >= 64;
-                if (on) {
-                    for (int i = 0; i < voices.length; i++) {
-                        if (voices[i].active && voices[i].on &&
-                                voices[i].channel == channel) {
-                            voices[i].sostenuto = true;
-                        }
-                    }
-                }
-                if (!on) {
-                    for (int i = 0; i < voices.length; i++) {
-                        if (voices[i].active && voices[i].sostenuto &&
-                                voices[i].channel == channel) {
-                            voices[i].sostenuto = false;
-                            if (!voices[i].on) {
-                                voices[i].on = true;
-                                voices[i].noteOff(0);
-                            }
-                        }
-                    }
-                }
-                break;
-            case 84:
-                portamento_control_note = value;
-                break;
-            case 98:
-                nrpn_control = (nrpn_control & (127 << 7)) + value;
-                rpn_control = RPN_NULL_VALUE;
-                break;
-            case 99:
-                nrpn_control = (nrpn_control & 127) + (value << 7);
-                rpn_control = RPN_NULL_VALUE;
-                break;
-            case 100:
-                rpn_control = (rpn_control & (127 << 7)) + value;
-                nrpn_control = RPN_NULL_VALUE;
-                break;
-            case 101:
-                rpn_control = (rpn_control & 127) + (value << 7);
-                nrpn_control = RPN_NULL_VALUE;
-                break;
-            case 120:
-                allSoundOff();
-                break;
-            case 121:
-                resetAllControllers(value == 127);
-                break;
-            case 122:
-                localControl(value >= 64);
-                break;
-            case 123:
-                allNotesOff();
-                break;
-            case 124:
-                setOmni(false);
-                break;
-            case 125:
-                setOmni(true);
-                break;
-            case 126:
-                if (value == 1)
-                    setMono(true);
-                break;
-            case 127:
-                setMono(false);
-                break;
-
-            default:
-                break;
-            }
-
-            co_midi_cc_cc[controller][0] = value * (1.0 / 128.0);
-
-            if (controller == 0x00) {
-                bank = (bank & 127) + (value << 7);
-                return;
-            }
-
-            if (controller == 0x20) {
-                bank = (bank & (127 << 7)) + value;
-                return;
-            }
-
-            this.controller[controller] = value;
-
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active)
-                    voices[i].controlChange(controller, value);
-
-        }
-    }
-
-    public int getController(int controller) {
-        synchronized (control_mutex) {
-            return this.controller[controller];
-        }
-    }
-
-    public void tuningChange(int program) {
-        tuningChange(0, program);
-    }
-
-    public void tuningChange(int bank, int program) {
-        synchronized (control_mutex) {
-            tuning = synthesizer.getTuning(new Patch(bank, program));
-        }
-    }
-
-    public void programChange(int program) {
-        programChange(bank, program);
-    }
-
-    public void programChange(int bank, int program) {
-        synchronized (control_mutex) {
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-            this.bank = bank;
-            this.program = program;
-            current_instrument = null;
-        }
-    }
-
-    public int getProgram() {
-        synchronized (control_mutex) {
-            return program;
-        }
-    }
-
-    public void setPitchBend(int bend) {
-        if (current_mixer != null)
-            current_mixer.setPitchBend(bend);
-        synchronized (control_mutex) {
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-            co_midi_pitch[0] = bend * (1.0 / 16384.0);
-            pitchbend = bend;
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active)
-                    voices[i].setPitchBend(bend);
-        }
-    }
-
-    public int getPitchBend() {
-        synchronized (control_mutex) {
-            return pitchbend;
-        }
-    }
-
-    public void nrpnChange(int controller, int value) {
-
-        /*
-        System.out.println("(" + channel + ").nrpnChange("
-                + Integer.toHexString(controller >> 7)
-                + " " + Integer.toHexString(controller & 127)
-                + ", " + Integer.toHexString(value >> 7)
-                + " " + Integer.toHexString(value & 127) + ")");
-         */
-
-        if (synthesizer.getGeneralMidiMode() == 0) {
-            if (controller == (0x01 << 7) + (0x08)) // Vibrato Rate
-                controlChange(76, value >> 7);
-            if (controller == (0x01 << 7) + (0x09)) // Vibrato Depth
-                controlChange(77, value >> 7);
-            if (controller == (0x01 << 7) + (0x0A)) // Vibrato Delay
-                controlChange(78, value >> 7);
-            if (controller == (0x01 << 7) + (0x20)) // Brightness
-                controlChange(74, value >> 7);
-            if (controller == (0x01 << 7) + (0x21)) // Filter Resonance
-                controlChange(71, value >> 7);
-            if (controller == (0x01 << 7) + (0x63)) // Attack Time
-                controlChange(73, value >> 7);
-            if (controller == (0x01 << 7) + (0x64)) // Decay Time
-                controlChange(75, value >> 7);
-            if (controller == (0x01 << 7) + (0x66)) // Release Time
-                controlChange(72, value >> 7);
-
-            if (controller >> 7 == 0x18) // Pitch coarse
-                controlChangePerNote(controller % 128, 120, value >> 7);
-            if (controller >> 7 == 0x1A) // Volume
-                controlChangePerNote(controller % 128, 7, value >> 7);
-            if (controller >> 7 == 0x1C) // Panpot
-                controlChangePerNote(controller % 128, 10, value >> 7);
-            if (controller >> 7 == 0x1D) // Reverb
-                controlChangePerNote(controller % 128, 91, value >> 7);
-            if (controller >> 7 == 0x1E) // Chorus
-                controlChangePerNote(controller % 128, 93, value >> 7);
-        }
-
-        int[] val_i = co_midi_nrpn_nrpn_i.get(controller);
-        double[] val_d = co_midi_nrpn_nrpn.get(controller);
-        if (val_i == null) {
-            val_i = new int[1];
-            co_midi_nrpn_nrpn_i.put(controller, val_i);
-        }
-        if (val_d == null) {
-            val_d = new double[1];
-            co_midi_nrpn_nrpn.put(controller, val_d);
-        }
-        val_i[0] = value;
-        val_d[0] = val_i[0] * (1.0 / 16384.0);
-
-        for (int i = 0; i < voices.length; i++)
-            if (voices[i].active)
-                voices[i].nrpnChange(controller, val_i[0]);
-
-    }
-
-    public void rpnChange(int controller, int value) {
-
-        /*
-        System.out.println("(" + channel + ").rpnChange("
-                + Integer.toHexString(controller >> 7)
-                + " " + Integer.toHexString(controller & 127)
-                + ", " + Integer.toHexString(value >> 7)
-                + " " + Integer.toHexString(value & 127) + ")");
-         */
-
-        if (controller == 3) {
-            tuning_program = (value >> 7) & 127;
-            tuningChange(tuning_bank, tuning_program);
-        }
-        if (controller == 4) {
-            tuning_bank = (value >> 7) & 127;
-        }
-
-        int[] val_i = co_midi_rpn_rpn_i.get(controller);
-        double[] val_d = co_midi_rpn_rpn.get(controller);
-        if (val_i == null) {
-            val_i = new int[1];
-            co_midi_rpn_rpn_i.put(controller, val_i);
-        }
-        if (val_d == null) {
-            val_d = new double[1];
-            co_midi_rpn_rpn.put(controller, val_d);
-        }
-        val_i[0] = value;
-        val_d[0] = val_i[0] * (1.0 / 16384.0);
-
-        for (int i = 0; i < voices.length; i++)
-            if (voices[i].active)
-                voices[i].rpnChange(controller, val_i[0]);
-    }
-
-    public void resetAllControllers() {
-        resetAllControllers(false);
-    }
-
-    public void resetAllControllers(boolean allControls) {
-        synchronized (control_mutex) {
-            mainmixer.msec_last_activity = mainmixer.msec_pos;
-
-            for (int i = 0; i < 128; i++) {
-                setPolyPressure(i, 0);
-            }
-            setChannelPressure(0);
-            setPitchBend(8192);
-            for (int i = 0; i < 128; i++) {
-                if (!dontResetControls[i])
-                    controlChange(i, 0);
-            }
-
-            controlChange(71, 64); // Filter Resonance
-            controlChange(72, 64); // Release Time
-            controlChange(73, 64); // Attack Time
-            controlChange(74, 64); // Brightness
-            controlChange(75, 64); // Decay Time
-            controlChange(76, 64); // Vibrato Rate
-            controlChange(77, 64); // Vibrato Depth
-            controlChange(78, 64); // Vibrato Delay
-
-            controlChange(8, 64); // Balance
-            controlChange(11, 127); // Expression
-            controlChange(98, 127); // NRPN Null
-            controlChange(99, 127); // NRPN Null
-            controlChange(100, 127); // RPN = Null
-            controlChange(101, 127); // RPN = Null
-
-            // see DLS 2.1 (Power-on Default Values)
-            if (allControls) {
-
-                keybasedcontroller_active = null;
-                keybasedcontroller_value = null;
-
-                controlChange(7, 100); // Volume
-                controlChange(10, 64); // Pan
-                controlChange(91, 40); // Reverb
-
-                for (int controller : co_midi_rpn_rpn.keySet()) {
-                    // don't reset tuning settings
-                    if (controller != 3 && controller != 4)
-                        rpnChange(controller, 0);
-                }
-                for (int controller : co_midi_nrpn_nrpn.keySet())
-                    nrpnChange(controller, 0);
-                rpnChange(0, 2 << 7);   // Bitch Bend sensitivity
-                rpnChange(1, 64 << 7);  // Channel fine tunning
-                rpnChange(2, 64 << 7);  // Channel Coarse Tuning
-                rpnChange(5, 64);       // Modulation Depth, +/- 50 cent
-
-                tuning_bank = 0;
-                tuning_program = 0;
-                tuning = new SoftTuning();
-
-            }
-
-        }
-    }
-
-    public void allNotesOff() {
-        if (current_mixer != null)
-            current_mixer.allNotesOff();
-        synchronized (control_mutex) {
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].on && voices[i].channel == channel
-                        && voices[i].releaseTriggered == false) {
-                    voices[i].noteOff(0);
-                }
-        }
-    }
-
-    public void allSoundOff() {
-        if (current_mixer != null)
-            current_mixer.allSoundOff();
-        synchronized (control_mutex) {
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].on && voices[i].channel == channel)
-                    voices[i].soundOff();
-        }
-    }
-
-    public boolean localControl(boolean on) {
-        return false;
-    }
-
-    public void setMono(boolean on) {
-        if (current_mixer != null)
-            current_mixer.setMono(on);
-        synchronized (control_mutex) {
-            allNotesOff();
-            mono = on;
-        }
-    }
-
-    public boolean getMono() {
-        synchronized (control_mutex) {
-            return mono;
-        }
-    }
-
-    public void setOmni(boolean on) {
-        if (current_mixer != null)
-            current_mixer.setOmni(on);
-        allNotesOff();
-    // Omni is not supported by GM2
-    }
-
-    public boolean getOmni() {
-        return false;
-    }
-
-    public void setMute(boolean mute) {
-        if (current_mixer != null)
-            current_mixer.setMute(mute);
-        synchronized (control_mutex) {
-            this.mute = mute;
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active && voices[i].channel == channel)
-                    voices[i].setMute(mute);
-        }
-    }
-
-    public boolean getMute() {
-        synchronized (control_mutex) {
-            return mute;
-        }
-    }
-
-    public void setSolo(boolean soloState) {
-        if (current_mixer != null)
-            current_mixer.setSolo(soloState);
-
-        synchronized (control_mutex) {
-            this.solo = soloState;
-
-            boolean soloinuse = false;
-            for (SoftChannel c : synthesizer.channels) {
-                if (c.solo) {
-                    soloinuse = true;
-                    break;
-                }
-            }
-
-            if (!soloinuse) {
-                for (SoftChannel c : synthesizer.channels)
-                    c.setSoloMute(false);
-                return;
-            }
-
-            for (SoftChannel c : synthesizer.channels)
-                c.setSoloMute(!c.solo);
-
-        }
-
-    }
-
-    private void setSoloMute(boolean mute) {
-        synchronized (control_mutex) {
-            if (solomute == mute)
-                return;
-            this.solomute = mute;
-            for (int i = 0; i < voices.length; i++)
-                if (voices[i].active && voices[i].channel == channel)
-                    voices[i].setSoloMute(solomute);
-        }
-    }
-
-    public boolean getSolo() {
-        synchronized (control_mutex) {
-            return solo;
-        }
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.Patch;
+
+/**
+ * Software Synthesizer MIDI channel class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftChannel implements MidiChannel, ModelDirectedPlayer {
+
+    private static boolean[] dontResetControls = new boolean[128];
+    static {
+        for (int i = 0; i < dontResetControls.length; i++)
+            dontResetControls[i] = false;
+
+        dontResetControls[0] = true;   // Bank Select (MSB)
+        dontResetControls[32] = true;  // Bank Select (LSB)
+        dontResetControls[7] = true;   // Channel Volume (MSB)
+        dontResetControls[8] = true;   // Balance (MSB)
+        dontResetControls[10] = true;  // Pan (MSB)
+        dontResetControls[11] = true;  // Expression (MSB)
+        dontResetControls[91] = true;  // Effects 1 Depth (default: Reverb Send)
+        dontResetControls[92] = true;  // Effects 2 Depth (default: Tremolo Depth)
+        dontResetControls[93] = true;  // Effects 3 Depth (default: Chorus Send)
+        dontResetControls[94] = true;  // Effects 4 Depth (default: Celeste [Detune] Depth)
+        dontResetControls[95] = true;  // Effects 5 Depth (default: Phaser Depth)
+        dontResetControls[70] = true;  // Sound Controller 1 (default: Sound Variation)
+        dontResetControls[71] = true;  // Sound Controller 2 (default: Timbre / Harmonic Quality)
+        dontResetControls[72] = true;  // Sound Controller 3 (default: Release Time)
+        dontResetControls[73] = true;  // Sound Controller 4 (default: Attack Time)
+        dontResetControls[74] = true;  // Sound Controller 5 (default: Brightness)
+        dontResetControls[75] = true;  // Sound Controller 6 (GM2 default: Decay Time)
+        dontResetControls[76] = true;  // Sound Controller 7 (GM2 default: Vibrato Rate)
+        dontResetControls[77] = true;  // Sound Controller 8 (GM2 default: Vibrato Depth)
+        dontResetControls[78] = true;  // Sound Controller 9 (GM2 default: Vibrato Delay)
+        dontResetControls[79] = true;  // Sound Controller 10 (GM2 default: Undefined)
+        dontResetControls[120] = true; // All Sound Off
+        dontResetControls[121] = true; // Reset All Controllers
+        dontResetControls[122] = true; // Local Control On/Off
+        dontResetControls[123] = true; // All Notes Off
+        dontResetControls[124] = true; // Omni Mode Off
+        dontResetControls[125] = true; // Omni Mode On
+        dontResetControls[126] = true; // Poly Mode Off
+        dontResetControls[127] = true; // Poly Mode On
+
+        dontResetControls[6] = true;   // Data Entry (MSB)
+        dontResetControls[38] = true;  // Data Entry (LSB)
+        dontResetControls[96] = true;  // Data Increment
+        dontResetControls[97] = true;  // Data Decrement
+        dontResetControls[98] = true;  // Non-Registered Parameter Number (LSB)
+        dontResetControls[99] = true;  // Non-Registered Parameter Number(MSB)
+        dontResetControls[100] = true; // RPN = Null
+        dontResetControls[101] = true; // RPN = Null
+
+    }
+
+    private static final int RPN_NULL_VALUE = (127 << 7) + 127;
+    private int rpn_control = RPN_NULL_VALUE;
+    private int nrpn_control = RPN_NULL_VALUE;
+    protected double portamento_time = 1; // keyschanges per control buffer time
+    protected int[] portamento_lastnote = new int[128];
+    protected int portamento_lastnote_ix = 0;
+    private int portamento_control_note = -1;
+    private boolean portamento = false;
+    private boolean mono = false;
+    private boolean mute = false;
+    private boolean solo = false;
+    private boolean solomute = false;
+    private Object control_mutex;
+    private int channel;
+    private SoftVoice[] voices;
+    private int bank;
+    private int program;
+    private SoftSynthesizer synthesizer;
+    private SoftMainMixer mainmixer;
+    private int[] polypressure = new int[128];
+    private int channelpressure = 0;
+    private int[] controller = new int[128];
+    private int pitchbend;
+    private double[] co_midi_pitch = new double[1];
+    private double[] co_midi_channel_pressure = new double[1];
+    protected SoftTuning tuning = new SoftTuning();
+    protected int tuning_bank = 0;
+    protected int tuning_program = 0;
+    protected SoftInstrument current_instrument = null;
+    protected ModelChannelMixer current_mixer = null;
+    private ModelDirector current_director = null;
+
+    // Controller Destination Settings
+    protected int cds_control_number = -1;
+    protected ModelConnectionBlock[] cds_control_connections = null;
+    protected ModelConnectionBlock[] cds_channelpressure_connections = null;
+    protected ModelConnectionBlock[] cds_polypressure_connections = null;
+    protected boolean sustain = false;
+    protected boolean[][] keybasedcontroller_active = null;
+    protected double[][] keybasedcontroller_value = null;
+
+    private class MidiControlObject implements SoftControl {
+        double[] pitch = co_midi_pitch;
+        double[] channel_pressure = co_midi_channel_pressure;
+        double[] poly_pressure = new double[1];
+
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("pitch"))
+                return pitch;
+            if (name.equals("channel_pressure"))
+                return channel_pressure;
+            if (name.equals("poly_pressure"))
+                return poly_pressure;
+            return null;
+        }
+    }
+
+    private SoftControl[] co_midi = new SoftControl[128];
+    {
+        for (int i = 0; i < co_midi.length; i++) {
+            co_midi[i] = new MidiControlObject();
+        }
+    }
+
+    private double[][] co_midi_cc_cc = new double[128][1];
+    private SoftControl co_midi_cc = new SoftControl() {
+        double[][] cc = co_midi_cc_cc;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            return cc[Integer.parseInt(name)];
+        }
+    };
+    Map<Integer, int[]> co_midi_rpn_rpn_i = new HashMap<Integer, int[]>();
+    Map<Integer, double[]> co_midi_rpn_rpn = new HashMap<Integer, double[]>();
+    private SoftControl co_midi_rpn = new SoftControl() {
+        Map<Integer, double[]> rpn = co_midi_rpn_rpn;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            int iname = Integer.parseInt(name);
+            double[] v = rpn.get(iname);
+            if (v == null) {
+                v = new double[1];
+                rpn.put(iname, v);
+            }
+            return v;
+        }
+    };
+    Map<Integer, int[]> co_midi_nrpn_nrpn_i = new HashMap<Integer, int[]>();
+    Map<Integer, double[]> co_midi_nrpn_nrpn = new HashMap<Integer, double[]>();
+    private SoftControl co_midi_nrpn = new SoftControl() {
+        Map<Integer, double[]> nrpn = co_midi_nrpn_nrpn;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            int iname = Integer.parseInt(name);
+            double[] v = nrpn.get(iname);
+            if (v == null) {
+                v = new double[1];
+                nrpn.put(iname, v);
+            }
+            return v;
+        }
+    };
+
+    public SoftChannel(SoftSynthesizer synth, int channel) {
+        this.channel = channel;
+        this.voices = synth.getVoices();
+        this.synthesizer = synth;
+        this.mainmixer = synth.getMainMixer();
+        control_mutex = synth.control_mutex;
+        resetAllControllers(true);
+    }
+
+    private int findFreeVoice(int x) {
+        for (int i = x; i < voices.length; i++)
+            if (!voices[i].active)
+                return i;
+
+        // No free voice was found, we must steal one
+
+        int vmode = synthesizer.getVoiceAllocationMode();
+        if (vmode == 1) {
+            // DLS Static Voice Allocation
+
+            //  * priority ( 10, 1-9, 11-16)
+            // Search for channel to steal from
+            int steal_channel = channel;
+            for (int j = 0; j < voices.length; j++) {
+                if (voices[j].stealer_channel == null) {
+                    if (steal_channel == 9) {
+                        steal_channel = voices[j].channel;
+                    } else {
+                        if (voices[j].channel != 9) {
+                            if (voices[j].channel > steal_channel)
+                                steal_channel = voices[j].channel;
+                        }
+                    }
+                }
+            }
+
+            int voiceNo = -1;
+
+            SoftVoice v = null;
+            // Search for oldest voice in off state on steal_channel
+            for (int j = 0; j < voices.length; j++) {
+                if (voices[j].channel == steal_channel) {
+                    if (voices[j].stealer_channel == null && !voices[j].on) {
+                        if (v == null) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                        if (voices[j].voiceID < v.voiceID) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                    }
+                }
+            }
+            // Search for oldest voice in on state on steal_channel
+            if (voiceNo == -1) {
+                for (int j = 0; j < voices.length; j++) {
+                    if (voices[j].channel == steal_channel) {
+                        if (voices[j].stealer_channel == null) {
+                            if (v == null) {
+                                v = voices[j];
+                                voiceNo = j;
+                            }
+                            if (voices[j].voiceID < v.voiceID) {
+                                v = voices[j];
+                                voiceNo = j;
+                            }
+                        }
+                    }
+                }
+            }
+
+            return voiceNo;
+
+        } else {
+            // Default Voice Allocation
+            //  * Find voice that is on
+            //          and Find voice which has lowest voiceID ( oldest voice)
+            //  * Or find voice that is off
+            //          and Find voice which has lowest voiceID ( oldest voice)
+
+            int voiceNo = -1;
+
+            SoftVoice v = null;
+            // Search for oldest voice in off state
+            for (int j = 0; j < voices.length; j++) {
+                if (voices[j].stealer_channel == null && !voices[j].on) {
+                    if (v == null) {
+                        v = voices[j];
+                        voiceNo = j;
+                    }
+                    if (voices[j].voiceID < v.voiceID) {
+                        v = voices[j];
+                        voiceNo = j;
+                    }
+                }
+            }
+            // Search for oldest voice in on state
+            if (voiceNo == -1) {
+
+                for (int j = 0; j < voices.length; j++) {
+                    if (voices[j].stealer_channel == null) {
+                        if (v == null) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                        if (voices[j].voiceID < v.voiceID) {
+                            v = voices[j];
+                            voiceNo = j;
+                        }
+                    }
+                }
+            }
+
+            return voiceNo;
+        }
+
+    }
+
+    protected void initVoice(SoftVoice voice, SoftPerformer p, int voiceID,
+            int noteNumber, int velocity, ModelConnectionBlock[] connectionBlocks,
+            ModelChannelMixer channelmixer, boolean releaseTriggered) {
+        if (voice.active) {
+            // Voice is active , we must steal the voice
+            voice.stealer_channel = this;
+            voice.stealer_performer = p;
+            voice.stealer_voiceID = voiceID;
+            voice.stealer_noteNumber = noteNumber;
+            voice.stealer_velocity = velocity;
+            voice.stealer_extendedConnectionBlocks = connectionBlocks;
+            voice.stealer_channelmixer = channelmixer;
+            voice.stealer_releaseTriggered = releaseTriggered;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active && voices[i].voiceID == voice.voiceID)
+                    voices[i].soundOff();
+            return;
+        }
+
+        voice.extendedConnectionBlocks = connectionBlocks;
+        voice.channelmixer = channelmixer;
+        voice.releaseTriggered = releaseTriggered;
+        voice.voiceID = voiceID;
+        voice.tuning = tuning;
+        voice.exclusiveClass = p.exclusiveClass;
+        voice.softchannel = this;
+        voice.channel = channel;
+        voice.bank = bank;
+        voice.program = program;
+        voice.instrument = current_instrument;
+        voice.performer = p;
+        voice.objects.clear();
+        voice.objects.put("midi", co_midi[noteNumber]);
+        voice.objects.put("midi_cc", co_midi_cc);
+        voice.objects.put("midi_rpn", co_midi_rpn);
+        voice.objects.put("midi_nrpn", co_midi_nrpn);
+        voice.noteOn(noteNumber, velocity);
+        voice.setMute(mute);
+        voice.setSoloMute(solomute);
+        if (releaseTriggered)
+            return;
+        if (portamento_control_note != -1) {
+            voice.co_noteon_keynumber[0]
+                    = (tuning.getTuning(portamento_control_note) / 100.0)
+                    * (1f / 128f);
+            voice.portamento = true;
+            portamento_control_note = -1;
+        } else if (portamento) {
+            if (mono) {
+                if (portamento_lastnote[0] != -1) {
+                    voice.co_noteon_keynumber[0]
+                            = (tuning.getTuning(portamento_lastnote[0]) / 100.0)
+                            * (1f / 128f);
+                    voice.portamento = true;
+                    portamento_control_note = -1;
+                }
+                portamento_lastnote[0] = noteNumber;
+            } else {
+                if (portamento_lastnote_ix != 0) {
+                    portamento_lastnote_ix--;
+                    voice.co_noteon_keynumber[0]
+                            = (tuning.getTuning(
+                                    portamento_lastnote[portamento_lastnote_ix])
+                                / 100.0)
+                            * (1f / 128f);
+                    voice.portamento = true;
+                }
+            }
+        }
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+
+        noteOn_internal(noteNumber, velocity);
+        if (current_mixer != null)
+            current_mixer.noteOn(noteNumber, velocity);
+    }
+
+    private void noteOn_internal(int noteNumber, int velocity) {
+
+        if (velocity == 0) {
+            noteOff_internal(noteNumber, 64);
+            return;
+        }
+
+        synchronized (control_mutex) {
+            if (sustain) {
+                sustain = false;
+                for (int i = 0; i < voices.length; i++) {
+                    if ((voices[i].sustain || voices[i].on)
+                            && voices[i].channel == channel && voices[i].active
+                            && voices[i].note == noteNumber) {
+                        voices[i].sustain = false;
+                        voices[i].on = true;
+                        voices[i].noteOff(0);
+                    }
+                }
+                sustain = true;
+            }
+
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+
+            if (mono) {
+                if (portamento) {
+                    boolean n_found = false;
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].on && voices[i].channel == channel
+                                && voices[i].active
+                                && voices[i].releaseTriggered == false) {
+                            voices[i].portamento = true;
+                            voices[i].setNote(noteNumber);
+                            n_found = true;
+                        }
+                    }
+                    if (n_found) {
+                        portamento_lastnote[0] = noteNumber;
+                        return;
+                    }
+                }
+
+                if (portamento_control_note != -1) {
+                    boolean n_found = false;
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].on && voices[i].channel == channel
+                                && voices[i].active
+                                && voices[i].note == portamento_control_note
+                                && voices[i].releaseTriggered == false) {
+                            voices[i].portamento = true;
+                            voices[i].setNote(noteNumber);
+                            n_found = true;
+                        }
+                    }
+                    portamento_control_note = -1;
+                    if (n_found)
+                        return;
+                }
+            }
+
+            if (mono)
+                allNotesOff();
+
+            if (current_instrument == null) {
+                current_instrument
+                        = synthesizer.findInstrument(program, bank, channel);
+                if (current_instrument == null)
+                    return;
+                if (current_mixer != null)
+                    mainmixer.stopMixer(current_mixer);
+                current_mixer = current_instrument.getSourceInstrument()
+                        .getChannelMixer(this, synthesizer.getFormat());
+                if (current_mixer != null)
+                    mainmixer.registerMixer(current_mixer);
+                current_director = current_instrument.getDirector(this, this);
+                applyInstrumentCustomization();
+            }
+            prevVoiceID = synthesizer.voiceIDCounter++;
+            firstVoice = true;
+            voiceNo = 0;
+
+            int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
+            play_noteNumber = noteNumber;
+            play_velocity = velocity;
+            play_releasetriggered = false;
+            lastVelocity[noteNumber] = velocity;
+            current_director.noteOn(tunedKey, velocity);
+
+            /*
+            SoftPerformer[] performers = current_instrument.getPerformers();
+            for (int i = 0; i < performers.length; i++) {
+                SoftPerformer p = performers[i];
+                if (p.keyFrom <= tunedKey && p.keyTo >= tunedKey) {
+                    if (p.velFrom <= velocity && p.velTo >= velocity) {
+                        if (firstVoice) {
+                            firstVoice = false;
+                            if (p.exclusiveClass != 0) {
+                                int x = p.exclusiveClass;
+                                for (int j = 0; j < voices.length; j++) {
+                                    if (voices[j].active
+                                            && voices[j].channel == channel
+                                            && voices[j].exclusiveClass == x) {
+                                        if (!(p.selfNonExclusive
+                                                && voices[j].note == noteNumber))
+                                            voices[j].shutdown();
+                                    }
+                                }
+                            }
+                        }
+                        voiceNo = findFreeVoice(voiceNo);
+                        if (voiceNo == -1)
+                            return;
+                        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber,
+                                velocity);
+                    }
+                }
+            }
+            */
+        }
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+        noteOff_internal(noteNumber, velocity);
+
+        if (current_mixer != null)
+            current_mixer.noteOff(noteNumber, velocity);
+    }
+
+    private void noteOff_internal(int noteNumber, int velocity) {
+        synchronized (control_mutex) {
+
+            if (!mono) {
+                if (portamento) {
+                    if (portamento_lastnote_ix != 127) {
+                        portamento_lastnote[portamento_lastnote_ix] = noteNumber;
+                        portamento_lastnote_ix++;
+                    }
+                }
+            }
+
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+            for (int i = 0; i < voices.length; i++) {
+                if (voices[i].on && voices[i].channel == channel
+                        && voices[i].note == noteNumber
+                        && voices[i].releaseTriggered == false) {
+                    voices[i].noteOff(velocity);
+                }
+            }
+
+            // Try play back note-off triggered voices,
+
+            if (current_instrument == null) {
+                current_instrument
+                        = synthesizer.findInstrument(program, bank, channel);
+                if (current_instrument == null)
+                    return;
+                if (current_mixer != null)
+                    mainmixer.stopMixer(current_mixer);
+                current_mixer = current_instrument.getSourceInstrument()
+                        .getChannelMixer(this, synthesizer.getFormat());
+                if (current_mixer != null)
+                    mainmixer.registerMixer(current_mixer);
+                current_director = current_instrument.getDirector(this, this);
+                applyInstrumentCustomization();
+
+            }
+            prevVoiceID = synthesizer.voiceIDCounter++;
+            firstVoice = true;
+            voiceNo = 0;
+
+            int tunedKey = (int)(Math.round(tuning.getTuning()[noteNumber]/100.0));
+            play_noteNumber = noteNumber;
+            play_velocity = lastVelocity[noteNumber];
+            play_releasetriggered = true;
+            current_director.noteOff(tunedKey, velocity);
+
+        }
+    }
+    private int[] lastVelocity = new int[128];
+    private int prevVoiceID;
+    private boolean firstVoice = true;
+    private int voiceNo = 0;
+    private int play_noteNumber = 0;
+    private int play_velocity = 0;
+    private boolean play_releasetriggered = false;
+
+    public void play(int performerIndex, ModelConnectionBlock[] connectionBlocks) {
+
+        int noteNumber = play_noteNumber;
+        int velocity = play_velocity;
+        boolean releasetriggered = play_releasetriggered;
+
+        SoftPerformer p = current_instrument.getPerformers()[performerIndex];
+
+        if (firstVoice) {
+            firstVoice = false;
+            if (p.exclusiveClass != 0) {
+                int x = p.exclusiveClass;
+                for (int j = 0; j < voices.length; j++) {
+                    if (voices[j].active && voices[j].channel == channel
+                            && voices[j].exclusiveClass == x) {
+                        if (!(p.selfNonExclusive && voices[j].note == noteNumber))
+                            voices[j].shutdown();
+                    }
+                }
+            }
+        }
+
+        voiceNo = findFreeVoice(voiceNo);
+
+        if (voiceNo == -1)
+            return;
+
+        initVoice(voices[voiceNo], p, prevVoiceID, noteNumber, velocity,
+                connectionBlocks, current_mixer, releasetriggered);
+    }
+
+    public void noteOff(int noteNumber) {
+        noteOff_internal(noteNumber, 64);
+    }
+
+    public void setPolyPressure(int noteNumber, int pressure) {
+        if (current_mixer != null)
+            current_mixer.setPolyPressure(noteNumber, pressure);
+
+        synchronized (control_mutex) {
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+            co_midi[noteNumber].get(0, "poly_pressure")[0] = pressure*(1.0/128.0);
+            polypressure[noteNumber] = pressure;
+            for (int i = 0; i < voices.length; i++) {
+                if (voices[i].active && voices[i].note == noteNumber)
+                    voices[i].setPolyPressure(pressure);
+            }
+        }
+    }
+
+    public int getPolyPressure(int noteNumber) {
+        synchronized (control_mutex) {
+            return polypressure[noteNumber];
+        }
+    }
+
+    public void setChannelPressure(int pressure) {
+        if (current_mixer != null)
+            current_mixer.setChannelPressure(pressure);
+        synchronized (control_mutex) {
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+            co_midi_channel_pressure[0] = pressure * (1.0 / 128.0);
+            channelpressure = pressure;
+            for (int i = 0; i < voices.length; i++) {
+                if (voices[i].active)
+                    voices[i].setChannelPressure(pressure);
+            }
+        }
+    }
+
+    public int getChannelPressure() {
+        synchronized (control_mutex) {
+            return channelpressure;
+        }
+    }
+
+    protected void applyInstrumentCustomization() {
+        if (cds_control_connections == null
+                && cds_channelpressure_connections == null
+                && cds_polypressure_connections == null) {
+            return;
+        }
+
+        ModelInstrument src_instrument = current_instrument.getSourceInstrument();
+        ModelPerformer[] performers = src_instrument.getPerformers();
+        ModelPerformer[] new_performers = new ModelPerformer[performers.length];
+        for (int i = 0; i < new_performers.length; i++) {
+            ModelPerformer performer = performers[i];
+            ModelPerformer new_performer = new ModelPerformer();
+            new_performer.setName(performer.getName());
+            new_performer.setExclusiveClass(performer.getExclusiveClass());
+            new_performer.setKeyFrom(performer.getKeyFrom());
+            new_performer.setKeyTo(performer.getKeyTo());
+            new_performer.setVelFrom(performer.getVelFrom());
+            new_performer.setVelTo(performer.getVelTo());
+            new_performer.getOscillators().addAll(performer.getOscillators());
+            new_performer.getConnectionBlocks().addAll(
+                    performer.getConnectionBlocks());
+            new_performers[i] = new_performer;
+
+            List<ModelConnectionBlock> connblocks =
+                    new_performer.getConnectionBlocks();
+
+            if (cds_control_connections != null) {
+                String cc = Integer.toString(cds_control_number);
+                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
+                while (iter.hasNext()) {
+                    ModelConnectionBlock conn = iter.next();
+                    ModelSource[] sources = conn.getSources();
+                    boolean removeok = false;
+                    if (sources != null) {
+                        for (int j = 0; j < sources.length; j++) {
+                            ModelSource src = sources[j];
+                            if ("midi_cc".equals(src.getIdentifier().getObject())
+                                    && cc.equals(src.getIdentifier().getVariable())) {
+                                removeok = true;
+                            }
+                        }
+                    }
+                    if (removeok)
+                        iter.remove();
+                }
+                for (int j = 0; j < cds_control_connections.length; j++)
+                    connblocks.add(cds_control_connections[j]);
+            }
+
+            if (cds_polypressure_connections != null) {
+                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
+                while (iter.hasNext()) {
+                    ModelConnectionBlock conn = iter.next();
+                    ModelSource[] sources = conn.getSources();
+                    boolean removeok = false;
+                    if (sources != null) {
+                        for (int j = 0; j < sources.length; j++) {
+                            ModelSource src = sources[j];
+                            if ("midi".equals(src.getIdentifier().getObject())
+                                    && "poly_pressure".equals(
+                                        src.getIdentifier().getVariable())) {
+                                removeok = true;
+                            }
+                        }
+                    }
+                    if (removeok)
+                        iter.remove();
+                }
+                for (int j = 0; j < cds_polypressure_connections.length; j++)
+                    connblocks.add(cds_polypressure_connections[j]);
+            }
+
+
+            if (cds_channelpressure_connections != null) {
+                Iterator<ModelConnectionBlock> iter = connblocks.iterator();
+                while (iter.hasNext()) {
+                    ModelConnectionBlock conn = iter.next();
+                    ModelSource[] sources = conn.getSources();
+                    boolean removeok = false;
+                    if (sources != null) {
+                        for (int j = 0; j < sources.length; j++) {
+                            ModelIdentifier srcid = sources[j].getIdentifier();
+                            if ("midi".equals(srcid.getObject()) &&
+                                    "channel_pressure".equals(srcid.getVariable())) {
+                                removeok = true;
+                            }
+                        }
+                    }
+                    if (removeok)
+                        iter.remove();
+                }
+                for (int j = 0; j < cds_channelpressure_connections.length; j++)
+                    connblocks.add(cds_channelpressure_connections[j]);
+            }
+
+        }
+
+        current_instrument = new SoftInstrument(src_instrument, new_performers);
+
+    }
+
+    private ModelConnectionBlock[] createModelConnections(ModelIdentifier sid,
+            int[] destination, int[] range) {
+
+        /*
+        controlled parameter (pp)|range (rr)| Description             |Default
+        -------------------------|----------|-------------------------|-------
+        00 Pitch Control         | 28H..58H | -24..+24 semitones      | 40H
+        01 Filter Cutoff Control | 00H..7FH | -9600..+9450 cents      | 40H
+        02 Amplitude Control     | 00H..7FH | 0..(127/64)*100 percent | 40H
+        03 LFO Pitch Depth       | 00H..7FH | 0..600 cents            |  0
+        04 LFO Filter Depth      | 00H..7FH | 0..2400 cents           |  0
+        05 LFO Amplitude Depth   | 00H..7FH | 0..100 percent          |  0
+        */
+
+        List<ModelConnectionBlock> conns = new ArrayList<ModelConnectionBlock>();
+
+        for (int i = 0; i < destination.length; i++) {
+            int d = destination[i];
+            int r = range[i];
+            if (d == 0) {
+                double scale = (r - 64) * 100;
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(sid,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        scale,
+                        new ModelDestination(
+                            new ModelIdentifier("osc", "pitch")));
+                conns.add(conn);
+
+            }
+            if (d == 1) {
+                double scale = (r / 64.0 - 1.0) * 9600.0;
+                ModelConnectionBlock conn;
+                if (scale > 0) {
+                    conn = new ModelConnectionBlock(
+                            new ModelSource(sid,
+                                ModelStandardTransform.DIRECTION_MAX2MIN,
+                                ModelStandardTransform.POLARITY_UNIPOLAR,
+                                ModelStandardTransform.TRANSFORM_LINEAR),
+                            -scale,
+                            new ModelDestination(
+                                ModelDestination.DESTINATION_FILTER_FREQ));
+                } else {
+                    conn = new ModelConnectionBlock(
+                            new ModelSource(sid,
+                                ModelStandardTransform.DIRECTION_MIN2MAX,
+                                ModelStandardTransform.POLARITY_UNIPOLAR,
+                                ModelStandardTransform.TRANSFORM_LINEAR),
+                            scale,
+                            new ModelDestination(
+                                ModelDestination.DESTINATION_FILTER_FREQ));
+                }
+                conns.add(conn);
+            }
+            if (d == 2) {
+                final double scale = (r / 64.0);
+                ModelTransform mt = new ModelTransform() {
+                    double s = scale;
+                    public double transform(double value) {
+                        if (s < 1)
+                            value = s + (value * (1.0 - s));
+                        else if (s > 1)
+                            value = 1 + (value * (s - 1.0));
+                        else
+                            return 0;
+                        return -((5.0 / 12.0) / Math.log(10)) * Math.log(value);
+                    }
+                };
+
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(sid, mt), -960,
+                        new ModelDestination(ModelDestination.DESTINATION_GAIN));
+                conns.add(conn);
+
+            }
+            if (d == 3) {
+                double scale = (r / 64.0 - 1.0) * 9600.0;
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_BIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(sid,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        scale,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_PITCH));
+                conns.add(conn);
+            }
+            if (d == 4) {
+                double scale = (r / 128.0) * 2400.0;
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_BIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(sid,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        scale,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_FILTER_FREQ));
+                conns.add(conn);
+            }
+            if (d == 5) {
+                final double scale = (r / 127.0);
+
+                ModelTransform mt = new ModelTransform() {
+                    double s = scale;
+                    public double transform(double value) {
+                        return -((5.0 / 12.0) / Math.log(10))
+                                * Math.log(1 - value * s);
+                    }
+                };
+
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                            ModelStandardTransform.DIRECTION_MIN2MAX,
+                            ModelStandardTransform.POLARITY_UNIPOLAR,
+                            ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(sid, mt),
+                        -960,
+                        new ModelDestination(
+                            ModelDestination.DESTINATION_GAIN));
+                conns.add(conn);
+            }
+        }
+
+        return conns.toArray(new ModelConnectionBlock[conns.size()]);
+    }
+
+    public void mapPolyPressureToDestination(int[] destination, int[] range) {
+        current_instrument = null;
+        if (destination.length == 0) {
+            cds_polypressure_connections = null;
+            return;
+        }
+        cds_polypressure_connections
+                = createModelConnections(
+                    new ModelIdentifier("midi", "poly_pressure"),
+                    destination, range);
+    }
+
+    public void mapChannelPressureToDestination(int[] destination, int[] range) {
+        current_instrument = null;
+        if (destination.length == 0) {
+            cds_channelpressure_connections = null;
+            return;
+        }
+        cds_channelpressure_connections
+                = createModelConnections(
+                    new ModelIdentifier("midi", "channel_pressure"),
+                    destination, range);
+    }
+
+    public void mapControlToDestination(int control, int[] destination, int[] range) {
+
+        if (!((control >= 0x01 && control <= 0x1F)
+                || (control >= 0x40 && control <= 0x5F))) {
+            cds_control_connections = null;
+            return;
+        }
+
+        current_instrument = null;
+        cds_control_number = control;
+        if (destination.length == 0) {
+            cds_control_connections = null;
+            return;
+        }
+        cds_control_connections
+                = createModelConnections(
+                    new ModelIdentifier("midi_cc", Integer.toString(control)),
+                    destination, range);
+    }
+
+    public void controlChangePerNote(int noteNumber, int controller, int value) {
+
+/*
+ CC# | nn   | Name                    | vv             | default    | description
+-----|------|-------------------------|----------------|------------|-------------------------------
+7    |07H   |Note Volume              |00H-40H-7FH     |40H         |0-100-(127/64)*100(%)(Relative)
+10   |0AH   |*Pan                     |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
+33-63|21-3FH|LSB for                  |01H-1FH         |            |
+71   |47H   |Timbre/Harmonic Intensity|00H-40H-7FH     |40H (???)   |
+72   |48H   |Release Time             |00H-40H-7FH     |40H (???)   |
+73   |49H   |Attack Time              |00H-40H-7FH     |40H (???)   |
+74   |4AH   |Brightness               |00H-40H-7FH     |40H (???)   |
+75   |4BH   |Decay Time               |00H-40H-7FH     |40H (???)   |
+76   |4CH   |Vibrato Rate             |00H-40H-7FH     |40H (???)   |
+77   |4DH   |Vibrato Depth            |00H-40H-7FH     |40H (???)   |
+78   |4EH   |Vibrato Delay            |00H-40H-7FH     |40H (???)   |
+91   |5BH   |*Reverb Send             |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
+93   |5DH   |*Chorus Send             |00H-7FH absolute|Preset Value|Left-Center-Right (absolute)
+120  |78H   |**Fine Tuning            |00H-40H-7FH     |40H (???)   |
+121  |79H   |**Coarse Tuning          |00H-40H-7FH     |40H (???)   |
+*/
+
+        if (keybasedcontroller_active == null) {
+            keybasedcontroller_active = new boolean[128][];
+            keybasedcontroller_value = new double[128][];
+        }
+        if (keybasedcontroller_active[noteNumber] == null) {
+            keybasedcontroller_active[noteNumber] = new boolean[128];
+            Arrays.fill(keybasedcontroller_active[noteNumber], false);
+            keybasedcontroller_value[noteNumber] = new double[128];
+            Arrays.fill(keybasedcontroller_value[noteNumber], 0);
+        }
+
+        if (value == -1) {
+            keybasedcontroller_active[noteNumber][controller] = false;
+        } else {
+            keybasedcontroller_active[noteNumber][controller] = true;
+            keybasedcontroller_value[noteNumber][controller] = value / 128.0;
+        }
+
+        if (controller < 120) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].controlChange(controller, -1);
+        } else if (controller == 120) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].rpnChange(1, -1);
+        } else if (controller == 121) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].rpnChange(2, -1);
+        }
+
+    }
+
+    public int getControlPerNote(int noteNumber, int controller) {
+        if (keybasedcontroller_active == null)
+            return -1;
+        if (keybasedcontroller_active[noteNumber] == null)
+            return -1;
+        if (!keybasedcontroller_active[noteNumber][controller])
+            return -1;
+        return (int)(keybasedcontroller_value[noteNumber][controller] * 128);
+    }
+
+    public void controlChange(int controller, int value) {
+        if (current_mixer != null)
+            current_mixer.controlChange(controller, value);
+
+        synchronized (control_mutex) {
+            switch (controller) {
+            /*
+            Map<String, int[]>co_midi_rpn_rpn_i = new HashMap<String, int[]>();
+            Map<String, double[]>co_midi_rpn_rpn = new HashMap<String, double[]>();
+            Map<String, int[]>co_midi_nrpn_nrpn_i = new HashMap<String, int[]>();
+            Map<String, double[]>co_midi_nrpn_nrpn = new HashMap<String, double[]>();
+             */
+
+            case 5:
+                // This produce asin-like curve
+                // as described in General Midi Level 2 Specification, page 6
+                double x = -Math.asin((value / 128.0) * 2 - 1) / Math.PI + 0.5;
+                x = Math.pow(100000.0, x) / 100.0;  // x is now cent/msec
+                // Convert x from cent/msec to key/controlbuffertime
+                x = x / 100.0;                      // x is now keys/msec
+                x = x * 1000.0;                     // x is now keys/sec
+                x = x / synthesizer.getControlRate(); // x is now keys/controlbuffertime
+                portamento_time = x;
+                break;
+            case 6:
+            case 38:
+            case 96:
+            case 97:
+                int val = 0;
+                if (nrpn_control != RPN_NULL_VALUE) {
+                    int[] val_i = co_midi_nrpn_nrpn_i.get(nrpn_control);
+                    if (val_i != null)
+                        val = val_i[0];
+                }
+                if (rpn_control != RPN_NULL_VALUE) {
+                    int[] val_i = co_midi_rpn_rpn_i.get(rpn_control);
+                    if (val_i != null)
+                        val = val_i[0];
+                }
+
+                if (controller == 6)
+                    val = (val & 127) + (value << 7);
+                else if (controller == 38)
+                    val = (val & (127 << 7)) + value;
+                else if (controller == 96 || controller == 97) {
+                    int step = 1;
+                    if (rpn_control == 2 || rpn_control == 3 || rpn_control == 4)
+                        step = 128;
+                    if (controller == 96)
+                        val += step;
+                    if (controller == 97)
+                        val -= step;
+                }
+
+                if (nrpn_control != RPN_NULL_VALUE)
+                    nrpnChange(nrpn_control, val);
+                if (rpn_control != RPN_NULL_VALUE)
+                    rpnChange(rpn_control, val);
+
+                break;
+            case 64: // Hold1 (Damper) (cc#64)
+                boolean on = value >= 64;
+                if (sustain != on) {
+                    sustain = on;
+                    if (!on) {
+                        for (int i = 0; i < voices.length; i++) {
+                            if (voices[i].active && voices[i].sustain &&
+                                    voices[i].channel == channel) {
+                                voices[i].sustain = false;
+                                if (!voices[i].on) {
+                                    voices[i].on = true;
+                                    voices[i].noteOff(0);
+                                }
+                            }
+                        }
+                    } else {
+                        for (int i = 0; i < voices.length; i++)
+                            if (voices[i].active && voices[i].channel == channel)
+                                voices[i].redamp();
+                    }
+                }
+                break;
+            case 65:
+                //allNotesOff();
+                portamento = value >= 64;
+                portamento_lastnote[0] = -1;
+                /*
+                for (int i = 0; i < portamento_lastnote.length; i++)
+                    portamento_lastnote[i] = -1;
+                 */
+                portamento_lastnote_ix = 0;
+                break;
+            case 66: // Sostenuto (cc#66)
+                on = value >= 64;
+                if (on) {
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].active && voices[i].on &&
+                                voices[i].channel == channel) {
+                            voices[i].sostenuto = true;
+                        }
+                    }
+                }
+                if (!on) {
+                    for (int i = 0; i < voices.length; i++) {
+                        if (voices[i].active && voices[i].sostenuto &&
+                                voices[i].channel == channel) {
+                            voices[i].sostenuto = false;
+                            if (!voices[i].on) {
+                                voices[i].on = true;
+                                voices[i].noteOff(0);
+                            }
+                        }
+                    }
+                }
+                break;
+            case 84:
+                portamento_control_note = value;
+                break;
+            case 98:
+                nrpn_control = (nrpn_control & (127 << 7)) + value;
+                rpn_control = RPN_NULL_VALUE;
+                break;
+            case 99:
+                nrpn_control = (nrpn_control & 127) + (value << 7);
+                rpn_control = RPN_NULL_VALUE;
+                break;
+            case 100:
+                rpn_control = (rpn_control & (127 << 7)) + value;
+                nrpn_control = RPN_NULL_VALUE;
+                break;
+            case 101:
+                rpn_control = (rpn_control & 127) + (value << 7);
+                nrpn_control = RPN_NULL_VALUE;
+                break;
+            case 120:
+                allSoundOff();
+                break;
+            case 121:
+                resetAllControllers(value == 127);
+                break;
+            case 122:
+                localControl(value >= 64);
+                break;
+            case 123:
+                allNotesOff();
+                break;
+            case 124:
+                setOmni(false);
+                break;
+            case 125:
+                setOmni(true);
+                break;
+            case 126:
+                if (value == 1)
+                    setMono(true);
+                break;
+            case 127:
+                setMono(false);
+                break;
+
+            default:
+                break;
+            }
+
+            co_midi_cc_cc[controller][0] = value * (1.0 / 128.0);
+
+            if (controller == 0x00) {
+                bank = (bank & 127) + (value << 7);
+                return;
+            }
+
+            if (controller == 0x20) {
+                bank = (bank & (127 << 7)) + value;
+                return;
+            }
+
+            this.controller[controller] = value;
+
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].controlChange(controller, value);
+
+        }
+    }
+
+    public int getController(int controller) {
+        synchronized (control_mutex) {
+            return this.controller[controller];
+        }
+    }
+
+    public void tuningChange(int program) {
+        tuningChange(0, program);
+    }
+
+    public void tuningChange(int bank, int program) {
+        synchronized (control_mutex) {
+            tuning = synthesizer.getTuning(new Patch(bank, program));
+        }
+    }
+
+    public void programChange(int program) {
+        programChange(bank, program);
+    }
+
+    public void programChange(int bank, int program) {
+        synchronized (control_mutex) {
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+            this.bank = bank;
+            this.program = program;
+            current_instrument = null;
+        }
+    }
+
+    public int getProgram() {
+        synchronized (control_mutex) {
+            return program;
+        }
+    }
+
+    public void setPitchBend(int bend) {
+        if (current_mixer != null)
+            current_mixer.setPitchBend(bend);
+        synchronized (control_mutex) {
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+            co_midi_pitch[0] = bend * (1.0 / 16384.0);
+            pitchbend = bend;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active)
+                    voices[i].setPitchBend(bend);
+        }
+    }
+
+    public int getPitchBend() {
+        synchronized (control_mutex) {
+            return pitchbend;
+        }
+    }
+
+    public void nrpnChange(int controller, int value) {
+
+        /*
+        System.out.println("(" + channel + ").nrpnChange("
+                + Integer.toHexString(controller >> 7)
+                + " " + Integer.toHexString(controller & 127)
+                + ", " + Integer.toHexString(value >> 7)
+                + " " + Integer.toHexString(value & 127) + ")");
+         */
+
+        if (synthesizer.getGeneralMidiMode() == 0) {
+            if (controller == (0x01 << 7) + (0x08)) // Vibrato Rate
+                controlChange(76, value >> 7);
+            if (controller == (0x01 << 7) + (0x09)) // Vibrato Depth
+                controlChange(77, value >> 7);
+            if (controller == (0x01 << 7) + (0x0A)) // Vibrato Delay
+                controlChange(78, value >> 7);
+            if (controller == (0x01 << 7) + (0x20)) // Brightness
+                controlChange(74, value >> 7);
+            if (controller == (0x01 << 7) + (0x21)) // Filter Resonance
+                controlChange(71, value >> 7);
+            if (controller == (0x01 << 7) + (0x63)) // Attack Time
+                controlChange(73, value >> 7);
+            if (controller == (0x01 << 7) + (0x64)) // Decay Time
+                controlChange(75, value >> 7);
+            if (controller == (0x01 << 7) + (0x66)) // Release Time
+                controlChange(72, value >> 7);
+
+            if (controller >> 7 == 0x18) // Pitch coarse
+                controlChangePerNote(controller % 128, 120, value >> 7);
+            if (controller >> 7 == 0x1A) // Volume
+                controlChangePerNote(controller % 128, 7, value >> 7);
+            if (controller >> 7 == 0x1C) // Panpot
+                controlChangePerNote(controller % 128, 10, value >> 7);
+            if (controller >> 7 == 0x1D) // Reverb
+                controlChangePerNote(controller % 128, 91, value >> 7);
+            if (controller >> 7 == 0x1E) // Chorus
+                controlChangePerNote(controller % 128, 93, value >> 7);
+        }
+
+        int[] val_i = co_midi_nrpn_nrpn_i.get(controller);
+        double[] val_d = co_midi_nrpn_nrpn.get(controller);
+        if (val_i == null) {
+            val_i = new int[1];
+            co_midi_nrpn_nrpn_i.put(controller, val_i);
+        }
+        if (val_d == null) {
+            val_d = new double[1];
+            co_midi_nrpn_nrpn.put(controller, val_d);
+        }
+        val_i[0] = value;
+        val_d[0] = val_i[0] * (1.0 / 16384.0);
+
+        for (int i = 0; i < voices.length; i++)
+            if (voices[i].active)
+                voices[i].nrpnChange(controller, val_i[0]);
+
+    }
+
+    public void rpnChange(int controller, int value) {
+
+        /*
+        System.out.println("(" + channel + ").rpnChange("
+                + Integer.toHexString(controller >> 7)
+                + " " + Integer.toHexString(controller & 127)
+                + ", " + Integer.toHexString(value >> 7)
+                + " " + Integer.toHexString(value & 127) + ")");
+         */
+
+        if (controller == 3) {
+            tuning_program = (value >> 7) & 127;
+            tuningChange(tuning_bank, tuning_program);
+        }
+        if (controller == 4) {
+            tuning_bank = (value >> 7) & 127;
+        }
+
+        int[] val_i = co_midi_rpn_rpn_i.get(controller);
+        double[] val_d = co_midi_rpn_rpn.get(controller);
+        if (val_i == null) {
+            val_i = new int[1];
+            co_midi_rpn_rpn_i.put(controller, val_i);
+        }
+        if (val_d == null) {
+            val_d = new double[1];
+            co_midi_rpn_rpn.put(controller, val_d);
+        }
+        val_i[0] = value;
+        val_d[0] = val_i[0] * (1.0 / 16384.0);
+
+        for (int i = 0; i < voices.length; i++)
+            if (voices[i].active)
+                voices[i].rpnChange(controller, val_i[0]);
+    }
+
+    public void resetAllControllers() {
+        resetAllControllers(false);
+    }
+
+    public void resetAllControllers(boolean allControls) {
+        synchronized (control_mutex) {
+            mainmixer.msec_last_activity = mainmixer.msec_pos;
+
+            for (int i = 0; i < 128; i++) {
+                setPolyPressure(i, 0);
+            }
+            setChannelPressure(0);
+            setPitchBend(8192);
+            for (int i = 0; i < 128; i++) {
+                if (!dontResetControls[i])
+                    controlChange(i, 0);
+            }
+
+            controlChange(71, 64); // Filter Resonance
+            controlChange(72, 64); // Release Time
+            controlChange(73, 64); // Attack Time
+            controlChange(74, 64); // Brightness
+            controlChange(75, 64); // Decay Time
+            controlChange(76, 64); // Vibrato Rate
+            controlChange(77, 64); // Vibrato Depth
+            controlChange(78, 64); // Vibrato Delay
+
+            controlChange(8, 64); // Balance
+            controlChange(11, 127); // Expression
+            controlChange(98, 127); // NRPN Null
+            controlChange(99, 127); // NRPN Null
+            controlChange(100, 127); // RPN = Null
+            controlChange(101, 127); // RPN = Null
+
+            // see DLS 2.1 (Power-on Default Values)
+            if (allControls) {
+
+                keybasedcontroller_active = null;
+                keybasedcontroller_value = null;
+
+                controlChange(7, 100); // Volume
+                controlChange(10, 64); // Pan
+                controlChange(91, 40); // Reverb
+
+                for (int controller : co_midi_rpn_rpn.keySet()) {
+                    // don't reset tuning settings
+                    if (controller != 3 && controller != 4)
+                        rpnChange(controller, 0);
+                }
+                for (int controller : co_midi_nrpn_nrpn.keySet())
+                    nrpnChange(controller, 0);
+                rpnChange(0, 2 << 7);   // Bitch Bend sensitivity
+                rpnChange(1, 64 << 7);  // Channel fine tunning
+                rpnChange(2, 64 << 7);  // Channel Coarse Tuning
+                rpnChange(5, 64);       // Modulation Depth, +/- 50 cent
+
+                tuning_bank = 0;
+                tuning_program = 0;
+                tuning = new SoftTuning();
+
+            }
+
+        }
+    }
+
+    public void allNotesOff() {
+        if (current_mixer != null)
+            current_mixer.allNotesOff();
+        synchronized (control_mutex) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].on && voices[i].channel == channel
+                        && voices[i].releaseTriggered == false) {
+                    voices[i].noteOff(0);
+                }
+        }
+    }
+
+    public void allSoundOff() {
+        if (current_mixer != null)
+            current_mixer.allSoundOff();
+        synchronized (control_mutex) {
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].on && voices[i].channel == channel)
+                    voices[i].soundOff();
+        }
+    }
+
+    public boolean localControl(boolean on) {
+        return false;
+    }
+
+    public void setMono(boolean on) {
+        if (current_mixer != null)
+            current_mixer.setMono(on);
+        synchronized (control_mutex) {
+            allNotesOff();
+            mono = on;
+        }
+    }
+
+    public boolean getMono() {
+        synchronized (control_mutex) {
+            return mono;
+        }
+    }
+
+    public void setOmni(boolean on) {
+        if (current_mixer != null)
+            current_mixer.setOmni(on);
+        allNotesOff();
+    // Omni is not supported by GM2
+    }
+
+    public boolean getOmni() {
+        return false;
+    }
+
+    public void setMute(boolean mute) {
+        if (current_mixer != null)
+            current_mixer.setMute(mute);
+        synchronized (control_mutex) {
+            this.mute = mute;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active && voices[i].channel == channel)
+                    voices[i].setMute(mute);
+        }
+    }
+
+    public boolean getMute() {
+        synchronized (control_mutex) {
+            return mute;
+        }
+    }
+
+    public void setSolo(boolean soloState) {
+        if (current_mixer != null)
+            current_mixer.setSolo(soloState);
+
+        synchronized (control_mutex) {
+            this.solo = soloState;
+
+            boolean soloinuse = false;
+            for (SoftChannel c : synthesizer.channels) {
+                if (c.solo) {
+                    soloinuse = true;
+                    break;
+                }
+            }
+
+            if (!soloinuse) {
+                for (SoftChannel c : synthesizer.channels)
+                    c.setSoloMute(false);
+                return;
+            }
+
+            for (SoftChannel c : synthesizer.channels)
+                c.setSoloMute(!c.solo);
+
+        }
+
+    }
+
+    private void setSoloMute(boolean mute) {
+        synchronized (control_mutex) {
+            if (solomute == mute)
+                return;
+            this.solomute = mute;
+            for (int i = 0; i < voices.length; i++)
+                if (voices[i].active && voices[i].channel == channel)
+                    voices[i].setSoloMute(solomute);
+        }
+    }
+
+    public boolean getSolo() {
+        synchronized (control_mutex) {
+            return solo;
+        }
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftChannelProxy.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChannelProxy.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,202 +1,202 @@
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.MidiChannel;
-
-/**
- * A MidiChannel proxy object used for external access to synthesizer internal
- * channel objects.
- *
- * @author Karl Helgason
- */
-public class SoftChannelProxy implements MidiChannel {
-
-    private MidiChannel channel = null;
-
-    public MidiChannel getChannel() {
-        return channel;
-    }
-
-    public void setChannel(MidiChannel channel) {
-        this.channel = channel;
-    }
-
-    public void allNotesOff() {
-        if (channel == null)
-            return;
-        channel.allNotesOff();
-    }
-
-    public void allSoundOff() {
-        if (channel == null)
-            return;
-        channel.allSoundOff();
-    }
-
-    public void controlChange(int controller, int value) {
-        if (channel == null)
-            return;
-        channel.controlChange(controller, value);
-    }
-
-    public int getChannelPressure() {
-        if (channel == null)
-            return 0;
-        return channel.getChannelPressure();
-    }
-
-    public int getController(int controller) {
-        if (channel == null)
-            return 0;
-        return channel.getController(controller);
-    }
-
-    public boolean getMono() {
-        if (channel == null)
-            return false;
-        return channel.getMono();
-    }
-
-    public boolean getMute() {
-        if (channel == null)
-            return false;
-        return channel.getMute();
-    }
-
-    public boolean getOmni() {
-        if (channel == null)
-            return false;
-        return channel.getOmni();
-    }
-
-    public int getPitchBend() {
-        if (channel == null)
-            return 8192;
-        return channel.getPitchBend();
-    }
-
-    public int getPolyPressure(int noteNumber) {
-        if (channel == null)
-            return 0;
-        return channel.getPolyPressure(noteNumber);
-    }
-
-    public int getProgram() {
-        if (channel == null)
-            return 0;
-        return channel.getProgram();
-    }
-
-    public boolean getSolo() {
-        if (channel == null)
-            return false;
-        return channel.getSolo();
-    }
-
-    public boolean localControl(boolean on) {
-        if (channel == null)
-            return false;
-        return channel.localControl(on);
-    }
-
-    public void noteOff(int noteNumber) {
-        if (channel == null)
-            return;
-        channel.noteOff(noteNumber);
-    }
-
-    public void noteOff(int noteNumber, int velocity) {
-        if (channel == null)
-            return;
-        channel.noteOff(noteNumber, velocity);
-    }
-
-    public void noteOn(int noteNumber, int velocity) {
-        if (channel == null)
-            return;
-        channel.noteOn(noteNumber, velocity);
-    }
-
-    public void programChange(int program) {
-        if (channel == null)
-            return;
-        channel.programChange(program);
-    }
-
-    public void programChange(int bank, int program) {
-        if (channel == null)
-            return;
-        channel.programChange(bank, program);
-    }
-
-    public void resetAllControllers() {
-        if (channel == null)
-            return;
-        channel.resetAllControllers();
-    }
-
-    public void setChannelPressure(int pressure) {
-        if (channel == null)
-            return;
-        channel.setChannelPressure(pressure);
-    }
-
-    public void setMono(boolean on) {
-        if (channel == null)
-            return;
-        channel.setMono(on);
-    }
-
-    public void setMute(boolean mute) {
-        if (channel == null)
-            return;
-        channel.setMute(mute);
-    }
-
-    public void setOmni(boolean on) {
-        if (channel == null)
-            return;
-        channel.setOmni(on);
-    }
-
-    public void setPitchBend(int bend) {
-        if (channel == null)
-            return;
-        channel.setPitchBend(bend);
-    }
-
-    public void setPolyPressure(int noteNumber, int pressure) {
-        if (channel == null)
-            return;
-        channel.setPolyPressure(noteNumber, pressure);
-    }
-
-    public void setSolo(boolean soloState) {
-        if (channel == null)
-            return;
-        channel.setSolo(soloState);
-    }
-}
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiChannel;
+
+/**
+ * A MidiChannel proxy object used for external access to synthesizer internal
+ * channel objects.
+ *
+ * @author Karl Helgason
+ */
+public class SoftChannelProxy implements MidiChannel {
+
+    private MidiChannel channel = null;
+
+    public MidiChannel getChannel() {
+        return channel;
+    }
+
+    public void setChannel(MidiChannel channel) {
+        this.channel = channel;
+    }
+
+    public void allNotesOff() {
+        if (channel == null)
+            return;
+        channel.allNotesOff();
+    }
+
+    public void allSoundOff() {
+        if (channel == null)
+            return;
+        channel.allSoundOff();
+    }
+
+    public void controlChange(int controller, int value) {
+        if (channel == null)
+            return;
+        channel.controlChange(controller, value);
+    }
+
+    public int getChannelPressure() {
+        if (channel == null)
+            return 0;
+        return channel.getChannelPressure();
+    }
+
+    public int getController(int controller) {
+        if (channel == null)
+            return 0;
+        return channel.getController(controller);
+    }
+
+    public boolean getMono() {
+        if (channel == null)
+            return false;
+        return channel.getMono();
+    }
+
+    public boolean getMute() {
+        if (channel == null)
+            return false;
+        return channel.getMute();
+    }
+
+    public boolean getOmni() {
+        if (channel == null)
+            return false;
+        return channel.getOmni();
+    }
+
+    public int getPitchBend() {
+        if (channel == null)
+            return 8192;
+        return channel.getPitchBend();
+    }
+
+    public int getPolyPressure(int noteNumber) {
+        if (channel == null)
+            return 0;
+        return channel.getPolyPressure(noteNumber);
+    }
+
+    public int getProgram() {
+        if (channel == null)
+            return 0;
+        return channel.getProgram();
+    }
+
+    public boolean getSolo() {
+        if (channel == null)
+            return false;
+        return channel.getSolo();
+    }
+
+    public boolean localControl(boolean on) {
+        if (channel == null)
+            return false;
+        return channel.localControl(on);
+    }
+
+    public void noteOff(int noteNumber) {
+        if (channel == null)
+            return;
+        channel.noteOff(noteNumber);
+    }
+
+    public void noteOff(int noteNumber, int velocity) {
+        if (channel == null)
+            return;
+        channel.noteOff(noteNumber, velocity);
+    }
+
+    public void noteOn(int noteNumber, int velocity) {
+        if (channel == null)
+            return;
+        channel.noteOn(noteNumber, velocity);
+    }
+
+    public void programChange(int program) {
+        if (channel == null)
+            return;
+        channel.programChange(program);
+    }
+
+    public void programChange(int bank, int program) {
+        if (channel == null)
+            return;
+        channel.programChange(bank, program);
+    }
+
+    public void resetAllControllers() {
+        if (channel == null)
+            return;
+        channel.resetAllControllers();
+    }
+
+    public void setChannelPressure(int pressure) {
+        if (channel == null)
+            return;
+        channel.setChannelPressure(pressure);
+    }
+
+    public void setMono(boolean on) {
+        if (channel == null)
+            return;
+        channel.setMono(on);
+    }
+
+    public void setMute(boolean mute) {
+        if (channel == null)
+            return;
+        channel.setMute(mute);
+    }
+
+    public void setOmni(boolean on) {
+        if (channel == null)
+            return;
+        channel.setOmni(on);
+    }
+
+    public void setPitchBend(int bend) {
+        if (channel == null)
+            return;
+        channel.setPitchBend(bend);
+    }
+
+    public void setPolyPressure(int noteNumber, int pressure) {
+        if (channel == null)
+            return;
+        channel.setPolyPressure(noteNumber, pressure);
+    }
+
+    public void setSolo(boolean soloState) {
+        if (channel == null)
+            return;
+        channel.setSolo(soloState);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftChorus.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftChorus.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,343 +1,343 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.Arrays;
-
-/**
- * A chorus effect made using LFO and variable delay. One for each channel
- * (left,right), with different starting phase for stereo effect.
- *
- * @author Karl Helgason
- */
-public class SoftChorus implements SoftAudioProcessor {
-
-    private class VariableDelay {
-
-        private float[] delaybuffer;
-        private int rovepos = 0;
-        private volatile float gain = 1;
-        private volatile float rgain = 0;
-        private volatile float delay = 0;
-        private float lastdelay = 0;
-        private volatile float feedback = 0;
-
-        public VariableDelay(int maxbuffersize) {
-            delaybuffer = new float[maxbuffersize];
-        }
-
-        public void setDelay(float delay) {
-            this.delay = delay;
-        }
-
-        public void setFeedBack(float feedback) {
-            this.feedback = feedback;
-        }
-
-        public void setGain(float gain) {
-            this.gain = gain;
-        }
-
-        public void setReverbSendGain(float rgain) {
-            this.rgain = rgain;
-        }
-
-        public void processMix(float[] in, float[] out, float[] rout) {
-            float gain = this.gain;
-            float delay = this.delay;
-            float feedback = this.feedback;
-
-            float[] delaybuffer = this.delaybuffer;
-            int len = in.length;
-            float delaydelta = (delay - lastdelay) / len;
-            int rnlen = delaybuffer.length;
-            int rovepos = this.rovepos;
-
-            if (rout == null)
-                for (int i = 0; i < len; i++) {
-                    float r = rovepos - (lastdelay + 2) + rnlen;
-                    int ri = (int) r;
-                    float s = r - ri;
-                    float a = delaybuffer[ri % rnlen];
-                    float b = delaybuffer[(ri + 1) % rnlen];
-                    float o = a * (1 - s) + b * (s);
-                    out[i] += o * gain;
-                    delaybuffer[rovepos] = in[i] + o * feedback;
-                    rovepos = (rovepos + 1) % rnlen;
-                    lastdelay += delaydelta;
-                }
-            else
-                for (int i = 0; i < len; i++) {
-                    float r = rovepos - (lastdelay + 2) + rnlen;
-                    int ri = (int) r;
-                    float s = r - ri;
-                    float a = delaybuffer[ri % rnlen];
-                    float b = delaybuffer[(ri + 1) % rnlen];
-                    float o = a * (1 - s) + b * (s);
-                    out[i] += o * gain;
-                    rout[i] += o * rgain;
-                    delaybuffer[rovepos] = in[i] + o * feedback;
-                    rovepos = (rovepos + 1) % rnlen;
-                    lastdelay += delaydelta;
-                }
-            this.rovepos = rovepos;
-            lastdelay = delay;
-        }
-
-        public void processReplace(float[] in, float[] out, float[] rout) {
-            Arrays.fill(out, 0);
-            Arrays.fill(rout, 0);
-            processMix(in, out, rout);
-        }
-    }
-
-    private class LFODelay {
-
-        private volatile double c_cos_delta;
-        private volatile double c_sin_delta;
-        private double c_cos = 1;
-        private double c_sin = 0;
-        private double depth = 0;
-        private VariableDelay vdelay;
-        private double samplerate;
-        private double controlrate;
-
-        public LFODelay(double samplerate, double controlrate) {
-            this.samplerate = samplerate;
-            this.controlrate = controlrate;
-            // vdelay = new VariableDelay((int)(samplerate*4));
-            vdelay = new VariableDelay((int) ((this.depth + 10) * 2));
-
-        }
-
-        public void setDepth(double depth) {
-            this.depth = depth * samplerate;
-            vdelay = new VariableDelay((int) ((this.depth + 10) * 2));
-        }
-
-        public void setRate(double rate) {
-            double g = (Math.PI * 2) * (rate / controlrate);
-            c_cos_delta = Math.cos(g);
-            c_sin_delta = Math.sin(g);
-        }
-
-        public void setPhase(double phase) {
-            c_cos = Math.cos(phase);
-            c_sin = Math.sin(phase);
-        }
-
-        public void setFeedBack(float feedback) {
-            vdelay.setFeedBack(feedback);
-        }
-
-        public void setGain(float gain) {
-            vdelay.setGain(gain);
-        }
-
-        public void setReverbSendGain(float rgain) {
-            vdelay.setReverbSendGain(rgain);
-        }
-
-        public void processMix(float[] in, float[] out, float[] rout) {
-            c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
-            c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
-            vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
-            vdelay.processMix(in, out, rout);
-        }
-
-        public void processReplace(float[] in, float[] out, float[] rout) {
-            c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
-            c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
-            vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
-            vdelay.processReplace(in, out, rout);
-
-        }
-    }
-    private boolean mix = true;
-    private SoftAudioBuffer inputA;
-    private SoftAudioBuffer left;
-    private SoftAudioBuffer right;
-    private SoftAudioBuffer reverb;
-    private LFODelay vdelay1L;
-    private LFODelay vdelay1R;
-    private float rgain = 0;
-    private SoftSynthesizer synth;
-    private boolean dirty = true;
-    private double dirty_vdelay1L_rate;
-    private double dirty_vdelay1R_rate;
-    private double dirty_vdelay1L_depth;
-    private double dirty_vdelay1R_depth;
-    private float dirty_vdelay1L_feedback;
-    private float dirty_vdelay1R_feedback;
-    private float dirty_vdelay1L_reverbsendgain;
-    private float dirty_vdelay1R_reverbsendgain;
-
-    public void init(SoftSynthesizer synth) {
-        this.synth = synth;
-        double samplerate = synth.getFormat().getSampleRate();
-        double controlrate = synth.getControlRate();
-        vdelay1L = new LFODelay(samplerate, controlrate);
-        vdelay1R = new LFODelay(samplerate, controlrate);
-        vdelay1L.setGain(1.0f); // %
-        vdelay1R.setGain(1.0f); // %
-        vdelay1L.setPhase(0.5 * Math.PI);
-        vdelay1R.setPhase(0);
-
-        globalParameterControlChange(new int[]{0x01 * 128 + 0x02}, 0, 2);
-    }
-
-    public void globalParameterControlChange(int[] slothpath, long param,
-            long value) {
-        if (slothpath.length == 1) {
-            if (slothpath[0] == 0x01 * 128 + 0x02) {
-                if (param == 0) { // Chorus Type
-                    switch ((int)value) {
-                    case 0: // Chorus 1 0 (0%) 3 (0.4Hz) 5 (1.9ms) 0 (0%)
-                        globalParameterControlChange(slothpath, 3, 0);
-                        globalParameterControlChange(slothpath, 1, 3);
-                        globalParameterControlChange(slothpath, 2, 5);
-                        globalParameterControlChange(slothpath, 4, 0);
-                        break;
-                    case 1: // Chorus 2 5 (4%) 9 (1.1Hz) 19 (6.3ms) 0 (0%)
-                        globalParameterControlChange(slothpath, 3, 5);
-                        globalParameterControlChange(slothpath, 1, 9);
-                        globalParameterControlChange(slothpath, 2, 19);
-                        globalParameterControlChange(slothpath, 4, 0);
-                        break;
-                    case 2: // Chorus 3 8 (6%) 3 (0.4Hz) 19 (6.3ms) 0 (0%)
-                        globalParameterControlChange(slothpath, 3, 8);
-                        globalParameterControlChange(slothpath, 1, 3);
-                        globalParameterControlChange(slothpath, 2, 19);
-                        globalParameterControlChange(slothpath, 4, 0);
-                        break;
-                    case 3: // Chorus 4 16 (12%) 9 (1.1Hz) 16 (5.3ms) 0 (0%)
-                        globalParameterControlChange(slothpath, 3, 16);
-                        globalParameterControlChange(slothpath, 1, 9);
-                        globalParameterControlChange(slothpath, 2, 16);
-                        globalParameterControlChange(slothpath, 4, 0);
-                        break;
-                    case 4: // FB Chorus 64 (49%) 2 (0.2Hz) 24 (7.8ms) 0 (0%)
-                        globalParameterControlChange(slothpath, 3, 64);
-                        globalParameterControlChange(slothpath, 1, 2);
-                        globalParameterControlChange(slothpath, 2, 24);
-                        globalParameterControlChange(slothpath, 4, 0);
-                        break;
-                    case 5: // Flanger 112 (86%) 1 (0.1Hz) 5 (1.9ms) 0 (0%)
-                        globalParameterControlChange(slothpath, 3, 112);
-                        globalParameterControlChange(slothpath, 1, 1);
-                        globalParameterControlChange(slothpath, 2, 5);
-                        globalParameterControlChange(slothpath, 4, 0);
-                        break;
-                    default:
-                        break;
-                    }
-                } else if (param == 1) { // Mod Rate
-                    dirty_vdelay1L_rate = (value * 0.122);
-                    dirty_vdelay1R_rate = (value * 0.122);
-                    dirty = true;
-                } else if (param == 2) { // Mod Depth
-                    dirty_vdelay1L_depth = ((value + 1) / 3200.0);
-                    dirty_vdelay1R_depth = ((value + 1) / 3200.0);
-                    dirty = true;
-                } else if (param == 3) { // Feedback
-                    dirty_vdelay1L_feedback = (value * 0.00763f);
-                    dirty_vdelay1R_feedback = (value * 0.00763f);
-                    dirty = true;
-                }
-                if (param == 4) { // Send to Reverb
-                    rgain = value * 0.00787f;
-                    dirty_vdelay1L_reverbsendgain = (value * 0.00787f);
-                    dirty_vdelay1R_reverbsendgain = (value * 0.00787f);
-                    dirty = true;
-                }
-
-            }
-        }
-    }
-
-    public void processControlLogic() {
-        if (dirty) {
-            dirty = false;
-            vdelay1L.setRate(dirty_vdelay1L_rate);
-            vdelay1R.setRate(dirty_vdelay1R_rate);
-            vdelay1L.setDepth(dirty_vdelay1L_depth);
-            vdelay1R.setDepth(dirty_vdelay1R_depth);
-            vdelay1L.setFeedBack(dirty_vdelay1L_feedback);
-            vdelay1R.setFeedBack(dirty_vdelay1R_feedback);
-            vdelay1L.setReverbSendGain(dirty_vdelay1L_reverbsendgain);
-            vdelay1R.setReverbSendGain(dirty_vdelay1R_reverbsendgain);
-        }
-    }
-    double silentcounter = 1000;
-
-    public void processAudio() {
-
-        if (inputA.isSilent()) {
-            silentcounter += 1 / synth.getControlRate();
-
-            if (silentcounter > 1) {
-                if (!mix) {
-                    left.clear();
-                    right.clear();
-                }
-                return;
-            }
-        } else
-            silentcounter = 0;
-
-        float[] inputA = this.inputA.array();
-        float[] left = this.left.array();
-        float[] right = this.right == null ? null : this.right.array();
-        float[] reverb = rgain != 0 ? this.reverb.array() : null;
-
-        if (mix) {
-            vdelay1L.processMix(inputA, left, reverb);
-            if (right != null)
-                vdelay1R.processMix(inputA, right, reverb);
-        } else {
-            vdelay1L.processReplace(inputA, left, reverb);
-            if (right != null)
-                vdelay1R.processReplace(inputA, right, reverb);
-        }
-    }
-
-    public void setInput(int pin, SoftAudioBuffer input) {
-        if (pin == 0)
-            inputA = input;
-    }
-
-    public void setMixMode(boolean mix) {
-        this.mix = mix;
-    }
-
-    public void setOutput(int pin, SoftAudioBuffer output) {
-        if (pin == 0)
-            left = output;
-        if (pin == 1)
-            right = output;
-        if (pin == 2)
-            reverb = output;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Arrays;
+
+/**
+ * A chorus effect made using LFO and variable delay. One for each channel
+ * (left,right), with different starting phase for stereo effect.
+ *
+ * @author Karl Helgason
+ */
+public class SoftChorus implements SoftAudioProcessor {
+
+    private class VariableDelay {
+
+        private float[] delaybuffer;
+        private int rovepos = 0;
+        private volatile float gain = 1;
+        private volatile float rgain = 0;
+        private volatile float delay = 0;
+        private float lastdelay = 0;
+        private volatile float feedback = 0;
+
+        public VariableDelay(int maxbuffersize) {
+            delaybuffer = new float[maxbuffersize];
+        }
+
+        public void setDelay(float delay) {
+            this.delay = delay;
+        }
+
+        public void setFeedBack(float feedback) {
+            this.feedback = feedback;
+        }
+
+        public void setGain(float gain) {
+            this.gain = gain;
+        }
+
+        public void setReverbSendGain(float rgain) {
+            this.rgain = rgain;
+        }
+
+        public void processMix(float[] in, float[] out, float[] rout) {
+            float gain = this.gain;
+            float delay = this.delay;
+            float feedback = this.feedback;
+
+            float[] delaybuffer = this.delaybuffer;
+            int len = in.length;
+            float delaydelta = (delay - lastdelay) / len;
+            int rnlen = delaybuffer.length;
+            int rovepos = this.rovepos;
+
+            if (rout == null)
+                for (int i = 0; i < len; i++) {
+                    float r = rovepos - (lastdelay + 2) + rnlen;
+                    int ri = (int) r;
+                    float s = r - ri;
+                    float a = delaybuffer[ri % rnlen];
+                    float b = delaybuffer[(ri + 1) % rnlen];
+                    float o = a * (1 - s) + b * (s);
+                    out[i] += o * gain;
+                    delaybuffer[rovepos] = in[i] + o * feedback;
+                    rovepos = (rovepos + 1) % rnlen;
+                    lastdelay += delaydelta;
+                }
+            else
+                for (int i = 0; i < len; i++) {
+                    float r = rovepos - (lastdelay + 2) + rnlen;
+                    int ri = (int) r;
+                    float s = r - ri;
+                    float a = delaybuffer[ri % rnlen];
+                    float b = delaybuffer[(ri + 1) % rnlen];
+                    float o = a * (1 - s) + b * (s);
+                    out[i] += o * gain;
+                    rout[i] += o * rgain;
+                    delaybuffer[rovepos] = in[i] + o * feedback;
+                    rovepos = (rovepos + 1) % rnlen;
+                    lastdelay += delaydelta;
+                }
+            this.rovepos = rovepos;
+            lastdelay = delay;
+        }
+
+        public void processReplace(float[] in, float[] out, float[] rout) {
+            Arrays.fill(out, 0);
+            Arrays.fill(rout, 0);
+            processMix(in, out, rout);
+        }
+    }
+
+    private class LFODelay {
+
+        private volatile double c_cos_delta;
+        private volatile double c_sin_delta;
+        private double c_cos = 1;
+        private double c_sin = 0;
+        private double depth = 0;
+        private VariableDelay vdelay;
+        private double samplerate;
+        private double controlrate;
+
+        public LFODelay(double samplerate, double controlrate) {
+            this.samplerate = samplerate;
+            this.controlrate = controlrate;
+            // vdelay = new VariableDelay((int)(samplerate*4));
+            vdelay = new VariableDelay((int) ((this.depth + 10) * 2));
+
+        }
+
+        public void setDepth(double depth) {
+            this.depth = depth * samplerate;
+            vdelay = new VariableDelay((int) ((this.depth + 10) * 2));
+        }
+
+        public void setRate(double rate) {
+            double g = (Math.PI * 2) * (rate / controlrate);
+            c_cos_delta = Math.cos(g);
+            c_sin_delta = Math.sin(g);
+        }
+
+        public void setPhase(double phase) {
+            c_cos = Math.cos(phase);
+            c_sin = Math.sin(phase);
+        }
+
+        public void setFeedBack(float feedback) {
+            vdelay.setFeedBack(feedback);
+        }
+
+        public void setGain(float gain) {
+            vdelay.setGain(gain);
+        }
+
+        public void setReverbSendGain(float rgain) {
+            vdelay.setReverbSendGain(rgain);
+        }
+
+        public void processMix(float[] in, float[] out, float[] rout) {
+            c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
+            c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
+            vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
+            vdelay.processMix(in, out, rout);
+        }
+
+        public void processReplace(float[] in, float[] out, float[] rout) {
+            c_cos = c_cos * c_cos_delta - c_sin * c_sin_delta;
+            c_sin = c_cos * c_sin_delta + c_sin * c_cos_delta;
+            vdelay.setDelay((float) (depth * 0.5 * (c_cos + 2)));
+            vdelay.processReplace(in, out, rout);
+
+        }
+    }
+    private boolean mix = true;
+    private SoftAudioBuffer inputA;
+    private SoftAudioBuffer left;
+    private SoftAudioBuffer right;
+    private SoftAudioBuffer reverb;
+    private LFODelay vdelay1L;
+    private LFODelay vdelay1R;
+    private float rgain = 0;
+    private SoftSynthesizer synth;
+    private boolean dirty = true;
+    private double dirty_vdelay1L_rate;
+    private double dirty_vdelay1R_rate;
+    private double dirty_vdelay1L_depth;
+    private double dirty_vdelay1R_depth;
+    private float dirty_vdelay1L_feedback;
+    private float dirty_vdelay1R_feedback;
+    private float dirty_vdelay1L_reverbsendgain;
+    private float dirty_vdelay1R_reverbsendgain;
+
+    public void init(SoftSynthesizer synth) {
+        this.synth = synth;
+        double samplerate = synth.getFormat().getSampleRate();
+        double controlrate = synth.getControlRate();
+        vdelay1L = new LFODelay(samplerate, controlrate);
+        vdelay1R = new LFODelay(samplerate, controlrate);
+        vdelay1L.setGain(1.0f); // %
+        vdelay1R.setGain(1.0f); // %
+        vdelay1L.setPhase(0.5 * Math.PI);
+        vdelay1R.setPhase(0);
+
+        globalParameterControlChange(new int[]{0x01 * 128 + 0x02}, 0, 2);
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value) {
+        if (slothpath.length == 1) {
+            if (slothpath[0] == 0x01 * 128 + 0x02) {
+                if (param == 0) { // Chorus Type
+                    switch ((int)value) {
+                    case 0: // Chorus 1 0 (0%) 3 (0.4Hz) 5 (1.9ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 0);
+                        globalParameterControlChange(slothpath, 1, 3);
+                        globalParameterControlChange(slothpath, 2, 5);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 1: // Chorus 2 5 (4%) 9 (1.1Hz) 19 (6.3ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 5);
+                        globalParameterControlChange(slothpath, 1, 9);
+                        globalParameterControlChange(slothpath, 2, 19);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 2: // Chorus 3 8 (6%) 3 (0.4Hz) 19 (6.3ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 8);
+                        globalParameterControlChange(slothpath, 1, 3);
+                        globalParameterControlChange(slothpath, 2, 19);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 3: // Chorus 4 16 (12%) 9 (1.1Hz) 16 (5.3ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 16);
+                        globalParameterControlChange(slothpath, 1, 9);
+                        globalParameterControlChange(slothpath, 2, 16);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 4: // FB Chorus 64 (49%) 2 (0.2Hz) 24 (7.8ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 64);
+                        globalParameterControlChange(slothpath, 1, 2);
+                        globalParameterControlChange(slothpath, 2, 24);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    case 5: // Flanger 112 (86%) 1 (0.1Hz) 5 (1.9ms) 0 (0%)
+                        globalParameterControlChange(slothpath, 3, 112);
+                        globalParameterControlChange(slothpath, 1, 1);
+                        globalParameterControlChange(slothpath, 2, 5);
+                        globalParameterControlChange(slothpath, 4, 0);
+                        break;
+                    default:
+                        break;
+                    }
+                } else if (param == 1) { // Mod Rate
+                    dirty_vdelay1L_rate = (value * 0.122);
+                    dirty_vdelay1R_rate = (value * 0.122);
+                    dirty = true;
+                } else if (param == 2) { // Mod Depth
+                    dirty_vdelay1L_depth = ((value + 1) / 3200.0);
+                    dirty_vdelay1R_depth = ((value + 1) / 3200.0);
+                    dirty = true;
+                } else if (param == 3) { // Feedback
+                    dirty_vdelay1L_feedback = (value * 0.00763f);
+                    dirty_vdelay1R_feedback = (value * 0.00763f);
+                    dirty = true;
+                }
+                if (param == 4) { // Send to Reverb
+                    rgain = value * 0.00787f;
+                    dirty_vdelay1L_reverbsendgain = (value * 0.00787f);
+                    dirty_vdelay1R_reverbsendgain = (value * 0.00787f);
+                    dirty = true;
+                }
+
+            }
+        }
+    }
+
+    public void processControlLogic() {
+        if (dirty) {
+            dirty = false;
+            vdelay1L.setRate(dirty_vdelay1L_rate);
+            vdelay1R.setRate(dirty_vdelay1R_rate);
+            vdelay1L.setDepth(dirty_vdelay1L_depth);
+            vdelay1R.setDepth(dirty_vdelay1R_depth);
+            vdelay1L.setFeedBack(dirty_vdelay1L_feedback);
+            vdelay1R.setFeedBack(dirty_vdelay1R_feedback);
+            vdelay1L.setReverbSendGain(dirty_vdelay1L_reverbsendgain);
+            vdelay1R.setReverbSendGain(dirty_vdelay1R_reverbsendgain);
+        }
+    }
+    double silentcounter = 1000;
+
+    public void processAudio() {
+
+        if (inputA.isSilent()) {
+            silentcounter += 1 / synth.getControlRate();
+
+            if (silentcounter > 1) {
+                if (!mix) {
+                    left.clear();
+                    right.clear();
+                }
+                return;
+            }
+        } else
+            silentcounter = 0;
+
+        float[] inputA = this.inputA.array();
+        float[] left = this.left.array();
+        float[] right = this.right == null ? null : this.right.array();
+        float[] reverb = rgain != 0 ? this.reverb.array() : null;
+
+        if (mix) {
+            vdelay1L.processMix(inputA, left, reverb);
+            if (right != null)
+                vdelay1R.processMix(inputA, right, reverb);
+        } else {
+            vdelay1L.processReplace(inputA, left, reverb);
+            if (right != null)
+                vdelay1R.processReplace(inputA, right, reverb);
+        }
+    }
+
+    public void setInput(int pin, SoftAudioBuffer input) {
+        if (pin == 0)
+            inputA = input;
+    }
+
+    public void setMixMode(boolean mix) {
+        this.mix = mix;
+    }
+
+    public void setOutput(int pin, SoftAudioBuffer output) {
+        if (pin == 0)
+            left = output;
+        if (pin == 1)
+            right = output;
+        if (pin == 2)
+            reverb = output;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftControl.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftControl.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,36 +1,36 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * <code>SoftControl</code> are the basic controls
- * used for control-rate processing.
- *
- * @author Karl Helgason
- */
-public interface SoftControl {
-
-    public double[] get(int instance, String name);
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * <code>SoftControl</code> are the basic controls
+ * used for control-rate processing.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftControl {
+
+    public double[] get(int instance, String name);
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftCubicResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftCubicResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,87 +1,87 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A resampler that uses third-order (cubic) interpolation.
- *
- * @author Karl Helgason
- */
-public class SoftCubicResampler extends SoftAbstractResampler {
-
-    public int getPadding() {
-        return 3;
-    }
-
-    public void interpolate(float[] in, float[] in_offset, float in_end,
-            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
-            int out_end) {
-        float pitch = startpitch[0];
-        float ix = in_offset[0];
-        int ox = out_offset[0];
-        float ix_end = in_end;
-        int ox_end = out_end;
-        if (pitchstep == 0) {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float fix = ix - iix;
-                float y0 = in[iix - 1];
-                float y1 = in[iix];
-                float y2 = in[iix + 1];
-                float y3 = in[iix + 2];
-                float a0 = y3 - y2 + y1 - y0;
-                float a1 = y0 - y1 - a0;
-                float a2 = y2 - y0;
-                float a3 = y1;
-                //float fix2 = fix * fix;
-                //out[ox++] = (a0 * fix + a1) * fix2 + (a2 * fix + a3);
-                out[ox++] = ((a0 * fix + a1) * fix + a2) * fix + a3;
-                ix += pitch;
-            }
-        } else {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float fix = ix - iix;
-                float y0 = in[iix - 1];
-                float y1 = in[iix];
-                float y2 = in[iix + 1];
-                float y3 = in[iix + 2];
-                float a0 = y3 - y2 + y1 - y0;
-                float a1 = y0 - y1 - a0;
-                float a2 = y2 - y0;
-                float a3 = y1;
-                //float fix2 = fix * fix;
-                //out[ox++] = (a0 * fix + a1) * fix2 + (a2 * fix + a3);
-                out[ox++] = ((a0 * fix + a1) * fix + a2) * fix + a3;
-                ix += pitch;
-                pitch += pitchstep;
-            }
-        }
-        in_offset[0] = ix;
-        out_offset[0] = ox;
-        startpitch[0] = pitch;
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses third-order (cubic) interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftCubicResampler extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 3;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0) {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float y0 = in[iix - 1];
+                float y1 = in[iix];
+                float y2 = in[iix + 1];
+                float y3 = in[iix + 2];
+                float a0 = y3 - y2 + y1 - y0;
+                float a1 = y0 - y1 - a0;
+                float a2 = y2 - y0;
+                float a3 = y1;
+                //float fix2 = fix * fix;
+                //out[ox++] = (a0 * fix + a1) * fix2 + (a2 * fix + a3);
+                out[ox++] = ((a0 * fix + a1) * fix + a2) * fix + a3;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float y0 = in[iix - 1];
+                float y1 = in[iix];
+                float y2 = in[iix + 1];
+                float y3 = in[iix + 2];
+                float a0 = y3 - y2 + y1 - y0;
+                float a1 = y0 - y1 - a0;
+                float a2 = y2 - y0;
+                float a3 = y1;
+                //float fix2 = fix * fix;
+                //out[ox++] = (a0 * fix + a1) * fix2 + (a2 * fix + a3);
+                out[ox++] = ((a0 * fix + a1) * fix + a2) * fix + a3;
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftEnvelopeGenerator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,298 +1,298 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * AHDSR control signal envelope generator.
- *
- * @author Karl Helgason
- */
-public class SoftEnvelopeGenerator implements SoftProcess {
-
-    public final static int EG_OFF = 0;
-    public final static int EG_DELAY = 1;
-    public final static int EG_ATTACK = 2;
-    public final static int EG_HOLD = 3;
-    public final static int EG_DECAY = 4;
-    public final static int EG_SUSTAIN = 5;
-    public final static int EG_RELEASE = 6;
-    public final static int EG_SHUTDOWN = 7;
-    public final static int EG_END = 8;
-    int max_count = 10;
-    int used_count = 0;
-    private int[] stage = new int[max_count];
-    private int[] stage_ix = new int[max_count];
-    private double[] stage_v = new double[max_count];
-    private int[] stage_count = new int[max_count];
-    private double[][] on = new double[max_count][1];
-    private double[][] active = new double[max_count][1];
-    private double[][] out = new double[max_count][1];
-    private double[][] delay = new double[max_count][1];
-    private double[][] attack = new double[max_count][1];
-    private double[][] hold = new double[max_count][1];
-    private double[][] decay = new double[max_count][1];
-    private double[][] sustain = new double[max_count][1];
-    private double[][] release = new double[max_count][1];
-    private double[][] shutdown = new double[max_count][1];
-    private double[][] release2 = new double[max_count][1];
-    private double[][] attack2 = new double[max_count][1];
-    private double[][] decay2 = new double[max_count][1];
-    private double control_time = 0;
-
-    public void reset() {
-        for (int i = 0; i < used_count; i++) {
-            stage[i] = 0;
-            on[i][0] = 0;
-            out[i][0] = 0;
-            delay[i][0] = 0;
-            attack[i][0] = 0;
-            hold[i][0] = 0;
-            decay[i][0] = 0;
-            sustain[i][0] = 0;
-            release[i][0] = 0;
-            shutdown[i][0] = 0;
-            attack2[i][0] = 0;
-            decay2[i][0] = 0;
-            release2[i][0] = 0;
-        }
-        used_count = 0;
-    }
-
-    public void init(SoftSynthesizer synth) {
-        control_time = 1.0 / synth.getControlRate();
-        processControlLogic();
-    }
-
-    public double[] get(int instance, String name) {
-        if (instance >= used_count)
-            used_count = instance + 1;
-        if (name == null)
-            return out[instance];
-        if (name.equals("on"))
-            return on[instance];
-        if (name.equals("active"))
-            return active[instance];
-        if (name.equals("delay"))
-            return delay[instance];
-        if (name.equals("attack"))
-            return attack[instance];
-        if (name.equals("hold"))
-            return hold[instance];
-        if (name.equals("decay"))
-            return decay[instance];
-        if (name.equals("sustain"))
-            return sustain[instance];
-        if (name.equals("release"))
-            return release[instance];
-        if (name.equals("shutdown"))
-            return shutdown[instance];
-        if (name.equals("attack2"))
-            return attack2[instance];
-        if (name.equals("decay2"))
-            return decay2[instance];
-        if (name.equals("release2"))
-            return release2[instance];
-
-        return null;
-    }
-
-    public void processControlLogic() {
-        for (int i = 0; i < used_count; i++) {
-
-            if (stage[i] == EG_END)
-                continue;
-
-            if ((stage[i] > EG_OFF) && (stage[i] < EG_RELEASE)) {
-                if (on[i][0] < 0.5) {
-                    if (on[i][0] < -0.5) {
-                        stage_count[i] = (int)(Math.pow(2,
-                                this.shutdown[i][0] / 1200.0) / control_time);
-                        if (stage_count[i] < 0)
-                            stage_count[i] = 0;
-                        stage_v[i] = out[i][0];
-                        stage_ix[i] = 0;
-                        stage[i] = EG_SHUTDOWN;
-                    } else {
-                        if ((release2[i][0] < 0.000001) && release[i][0] < 0
-                                && Double.isInfinite(release[i][0])) {
-                            out[i][0] = 0;
-                            active[i][0] = 0;
-                            stage[i] = EG_END;
-                            continue;
-                        }
-
-                        stage_count[i] = (int)(Math.pow(2,
-                                this.release[i][0] / 1200.0) / control_time);
-                        stage_count[i]
-                                += (int)(this.release2[i][0]/(control_time * 1000));
-                        if (stage_count[i] < 0)
-                            stage_count[i] = 0;
-                        // stage_v[i] = out[i][0];
-                        stage_ix[i] = 0;
-
-                        double m = 1 - out[i][0];
-                        stage_ix[i] = (int)(stage_count[i] * m);
-
-                        stage[i] = EG_RELEASE;
-                    }
-                }
-            }
-
-            switch (stage[i]) {
-            case EG_OFF:
-                active[i][0] = 1;
-                if (on[i][0] < 0.5)
-                    break;
-                stage[i] = EG_DELAY;
-                stage_ix[i] = (int)(Math.pow(2,
-                        this.delay[i][0] / 1200.0) / control_time);
-                if (stage_ix[i] < 0)
-                    stage_ix[i] = 0;
-            case EG_DELAY:
-                if (stage_ix[i] == 0) {
-                    double attack = this.attack[i][0];
-                    double attack2 = this.attack2[i][0];
-
-                    if (attack2 < 0.000001
-                            && (attack < 0 && Double.isInfinite(attack))) {
-                        out[i][0] = 1;
-                        stage[i] = EG_HOLD;
-                        stage_count[i] = (int)(Math.pow(2,
-                                this.hold[i][0] / 1200.0) / control_time);
-                        stage_ix[i] = 0;
-                    } else {
-                        stage[i] = EG_ATTACK;
-                        stage_count[i] = (int)(Math.pow(2,
-                                attack / 1200.0) / control_time);
-                        stage_count[i] += (int)(attack2 / (control_time * 1000));
-                        if (stage_count[i] < 0)
-                            stage_count[i] = 0;
-                        stage_ix[i] = 0;
-                    }
-                } else
-                    stage_ix[i]--;
-                break;
-            case EG_ATTACK:
-                stage_ix[i]++;
-                if (stage_ix[i] >= stage_count[i]) {
-                    out[i][0] = 1;
-                    stage[i] = EG_HOLD;
-                } else {
-                    // CONVEX attack
-                    double a = ((double)stage_ix[i]) / ((double)stage_count[i]);
-                    a = 1 + ((40.0 / 96.0) / Math.log(10)) * Math.log(a);
-                    if (a < 0)
-                        a = 0;
-                    else if (a > 1)
-                        a = 1;
-                    out[i][0] = a;
-                }
-                break;
-            case EG_HOLD:
-                stage_ix[i]++;
-                if (stage_ix[i] >= stage_count[i]) {
-                    stage[i] = EG_DECAY;
-                    stage_count[i] = (int)(Math.pow(2,
-                            this.decay[i][0] / 1200.0) / control_time);
-                    stage_count[i] += (int)(this.decay2[i][0]/(control_time*1000));
-                    if (stage_count[i] < 0)
-                        stage_count[i] = 0;
-                    stage_ix[i] = 0;
-                }
-                break;
-            case EG_DECAY:
-                stage_ix[i]++;
-                double sustain = this.sustain[i][0] * (1.0 / 1000.0);
-                if (stage_ix[i] >= stage_count[i]) {
-                    out[i][0] = sustain;
-                    stage[i] = EG_SUSTAIN;
-                    if (sustain < 0.001) {
-                        out[i][0] = 0;
-                        active[i][0] = 0;
-                        stage[i] = EG_END;
-                    }
-                } else {
-                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
-                    out[i][0] = (1 - m) + sustain * m;
-                }
-                break;
-            case EG_SUSTAIN:
-                break;
-            case EG_RELEASE:
-                stage_ix[i]++;
-                if (stage_ix[i] >= stage_count[i]) {
-                    out[i][0] = 0;
-                    active[i][0] = 0;
-                    stage[i] = EG_END;
-                } else {
-                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
-                    out[i][0] = (1 - m); // *stage_v[i];
-
-                    if (on[i][0] < -0.5) {
-                        stage_count[i] = (int)(Math.pow(2,
-                                this.shutdown[i][0] / 1200.0) / control_time);
-                        if (stage_count[i] < 0)
-                            stage_count[i] = 0;
-                        stage_v[i] = out[i][0];
-                        stage_ix[i] = 0;
-                        stage[i] = EG_SHUTDOWN;
-                    }
-
-                    // re-damping
-                    if (on[i][0] > 0.5) {
-                        sustain = this.sustain[i][0] * (1.0 / 1000.0);
-                        if (out[i][0] > sustain) {
-                            stage[i] = EG_DECAY;
-                            stage_count[i] = (int)(Math.pow(2,
-                                    this.decay[i][0] / 1200.0) / control_time);
-                            stage_count[i] +=
-                                    (int)(this.decay2[i][0]/(control_time*1000));
-                            if (stage_count[i] < 0)
-                                stage_count[i] = 0;
-                            m = (out[i][0] - 1) / (sustain - 1);
-                            stage_ix[i] = (int) (stage_count[i] * m);
-                        }
-                    }
-
-                }
-                break;
-            case EG_SHUTDOWN:
-                stage_ix[i]++;
-                if (stage_ix[i] >= stage_count[i]) {
-                    out[i][0] = 0;
-                    active[i][0] = 0;
-                    stage[i] = EG_END;
-                } else {
-                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
-                    out[i][0] = (1 - m) * stage_v[i];
-                }
-                break;
-            default:
-                break;
-            }
-        }
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * AHDSR control signal envelope generator.
+ *
+ * @author Karl Helgason
+ */
+public class SoftEnvelopeGenerator implements SoftProcess {
+
+    public final static int EG_OFF = 0;
+    public final static int EG_DELAY = 1;
+    public final static int EG_ATTACK = 2;
+    public final static int EG_HOLD = 3;
+    public final static int EG_DECAY = 4;
+    public final static int EG_SUSTAIN = 5;
+    public final static int EG_RELEASE = 6;
+    public final static int EG_SHUTDOWN = 7;
+    public final static int EG_END = 8;
+    int max_count = 10;
+    int used_count = 0;
+    private int[] stage = new int[max_count];
+    private int[] stage_ix = new int[max_count];
+    private double[] stage_v = new double[max_count];
+    private int[] stage_count = new int[max_count];
+    private double[][] on = new double[max_count][1];
+    private double[][] active = new double[max_count][1];
+    private double[][] out = new double[max_count][1];
+    private double[][] delay = new double[max_count][1];
+    private double[][] attack = new double[max_count][1];
+    private double[][] hold = new double[max_count][1];
+    private double[][] decay = new double[max_count][1];
+    private double[][] sustain = new double[max_count][1];
+    private double[][] release = new double[max_count][1];
+    private double[][] shutdown = new double[max_count][1];
+    private double[][] release2 = new double[max_count][1];
+    private double[][] attack2 = new double[max_count][1];
+    private double[][] decay2 = new double[max_count][1];
+    private double control_time = 0;
+
+    public void reset() {
+        for (int i = 0; i < used_count; i++) {
+            stage[i] = 0;
+            on[i][0] = 0;
+            out[i][0] = 0;
+            delay[i][0] = 0;
+            attack[i][0] = 0;
+            hold[i][0] = 0;
+            decay[i][0] = 0;
+            sustain[i][0] = 0;
+            release[i][0] = 0;
+            shutdown[i][0] = 0;
+            attack2[i][0] = 0;
+            decay2[i][0] = 0;
+            release2[i][0] = 0;
+        }
+        used_count = 0;
+    }
+
+    public void init(SoftSynthesizer synth) {
+        control_time = 1.0 / synth.getControlRate();
+        processControlLogic();
+    }
+
+    public double[] get(int instance, String name) {
+        if (instance >= used_count)
+            used_count = instance + 1;
+        if (name == null)
+            return out[instance];
+        if (name.equals("on"))
+            return on[instance];
+        if (name.equals("active"))
+            return active[instance];
+        if (name.equals("delay"))
+            return delay[instance];
+        if (name.equals("attack"))
+            return attack[instance];
+        if (name.equals("hold"))
+            return hold[instance];
+        if (name.equals("decay"))
+            return decay[instance];
+        if (name.equals("sustain"))
+            return sustain[instance];
+        if (name.equals("release"))
+            return release[instance];
+        if (name.equals("shutdown"))
+            return shutdown[instance];
+        if (name.equals("attack2"))
+            return attack2[instance];
+        if (name.equals("decay2"))
+            return decay2[instance];
+        if (name.equals("release2"))
+            return release2[instance];
+
+        return null;
+    }
+
+    public void processControlLogic() {
+        for (int i = 0; i < used_count; i++) {
+
+            if (stage[i] == EG_END)
+                continue;
+
+            if ((stage[i] > EG_OFF) && (stage[i] < EG_RELEASE)) {
+                if (on[i][0] < 0.5) {
+                    if (on[i][0] < -0.5) {
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.shutdown[i][0] / 1200.0) / control_time);
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        stage_v[i] = out[i][0];
+                        stage_ix[i] = 0;
+                        stage[i] = EG_SHUTDOWN;
+                    } else {
+                        if ((release2[i][0] < 0.000001) && release[i][0] < 0
+                                && Double.isInfinite(release[i][0])) {
+                            out[i][0] = 0;
+                            active[i][0] = 0;
+                            stage[i] = EG_END;
+                            continue;
+                        }
+
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.release[i][0] / 1200.0) / control_time);
+                        stage_count[i]
+                                += (int)(this.release2[i][0]/(control_time * 1000));
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        // stage_v[i] = out[i][0];
+                        stage_ix[i] = 0;
+
+                        double m = 1 - out[i][0];
+                        stage_ix[i] = (int)(stage_count[i] * m);
+
+                        stage[i] = EG_RELEASE;
+                    }
+                }
+            }
+
+            switch (stage[i]) {
+            case EG_OFF:
+                active[i][0] = 1;
+                if (on[i][0] < 0.5)
+                    break;
+                stage[i] = EG_DELAY;
+                stage_ix[i] = (int)(Math.pow(2,
+                        this.delay[i][0] / 1200.0) / control_time);
+                if (stage_ix[i] < 0)
+                    stage_ix[i] = 0;
+            case EG_DELAY:
+                if (stage_ix[i] == 0) {
+                    double attack = this.attack[i][0];
+                    double attack2 = this.attack2[i][0];
+
+                    if (attack2 < 0.000001
+                            && (attack < 0 && Double.isInfinite(attack))) {
+                        out[i][0] = 1;
+                        stage[i] = EG_HOLD;
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.hold[i][0] / 1200.0) / control_time);
+                        stage_ix[i] = 0;
+                    } else {
+                        stage[i] = EG_ATTACK;
+                        stage_count[i] = (int)(Math.pow(2,
+                                attack / 1200.0) / control_time);
+                        stage_count[i] += (int)(attack2 / (control_time * 1000));
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        stage_ix[i] = 0;
+                    }
+                } else
+                    stage_ix[i]--;
+                break;
+            case EG_ATTACK:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = 1;
+                    stage[i] = EG_HOLD;
+                } else {
+                    // CONVEX attack
+                    double a = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    a = 1 + ((40.0 / 96.0) / Math.log(10)) * Math.log(a);
+                    if (a < 0)
+                        a = 0;
+                    else if (a > 1)
+                        a = 1;
+                    out[i][0] = a;
+                }
+                break;
+            case EG_HOLD:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    stage[i] = EG_DECAY;
+                    stage_count[i] = (int)(Math.pow(2,
+                            this.decay[i][0] / 1200.0) / control_time);
+                    stage_count[i] += (int)(this.decay2[i][0]/(control_time*1000));
+                    if (stage_count[i] < 0)
+                        stage_count[i] = 0;
+                    stage_ix[i] = 0;
+                }
+                break;
+            case EG_DECAY:
+                stage_ix[i]++;
+                double sustain = this.sustain[i][0] * (1.0 / 1000.0);
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = sustain;
+                    stage[i] = EG_SUSTAIN;
+                    if (sustain < 0.001) {
+                        out[i][0] = 0;
+                        active[i][0] = 0;
+                        stage[i] = EG_END;
+                    }
+                } else {
+                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    out[i][0] = (1 - m) + sustain * m;
+                }
+                break;
+            case EG_SUSTAIN:
+                break;
+            case EG_RELEASE:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = 0;
+                    active[i][0] = 0;
+                    stage[i] = EG_END;
+                } else {
+                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    out[i][0] = (1 - m); // *stage_v[i];
+
+                    if (on[i][0] < -0.5) {
+                        stage_count[i] = (int)(Math.pow(2,
+                                this.shutdown[i][0] / 1200.0) / control_time);
+                        if (stage_count[i] < 0)
+                            stage_count[i] = 0;
+                        stage_v[i] = out[i][0];
+                        stage_ix[i] = 0;
+                        stage[i] = EG_SHUTDOWN;
+                    }
+
+                    // re-damping
+                    if (on[i][0] > 0.5) {
+                        sustain = this.sustain[i][0] * (1.0 / 1000.0);
+                        if (out[i][0] > sustain) {
+                            stage[i] = EG_DECAY;
+                            stage_count[i] = (int)(Math.pow(2,
+                                    this.decay[i][0] / 1200.0) / control_time);
+                            stage_count[i] +=
+                                    (int)(this.decay2[i][0]/(control_time*1000));
+                            if (stage_count[i] < 0)
+                                stage_count[i] = 0;
+                            m = (out[i][0] - 1) / (sustain - 1);
+                            stage_ix[i] = (int) (stage_count[i] * m);
+                        }
+                    }
+
+                }
+                break;
+            case EG_SHUTDOWN:
+                stage_ix[i]++;
+                if (stage_ix[i] >= stage_count[i]) {
+                    out[i][0] = 0;
+                    active[i][0] = 0;
+                    stage[i] = EG_END;
+                } else {
+                    double m = ((double)stage_ix[i]) / ((double)stage_count[i]);
+                    out[i][0] = (1 - m) * stage_v[i];
+                }
+                break;
+            default:
+                break;
+            }
+        }
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftFilter.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,614 +1,614 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Infinite impulse response (IIR) filter class.
- *
- * The filters where implemented and adapted using algorithms from musicdsp.org
- * archive: 1-RC and C filter, Simple 2-pole LP LP and HP filter, biquad,
- * tweaked butterworth RBJ Audio-EQ-Cookbook, EQ filter kookbook
- *
- * @author Karl Helgason
- */
-public class SoftFilter {
-
-    public static int FILTERTYPE_LP6 = 0x00;
-    public static int FILTERTYPE_LP12 = 0x01;
-    public static int FILTERTYPE_HP12 = 0x11;
-    public static int FILTERTYPE_BP12 = 0x21;
-    public static int FILTERTYPE_NP12 = 0x31;
-    public static int FILTERTYPE_LP24 = 0x03;
-    public static int FILTERTYPE_HP24 = 0x13;
-
-    //
-    // 0x0 = 1st-order, 6 dB/oct
-    // 0x1 = 2nd-order, 12 dB/oct
-    // 0x2 = 3rd-order, 18 dB/oct
-    // 0x3 = 4th-order, 24 db/oct
-    //
-    // 0x00 = LP, Low Pass Filter
-    // 0x10 = HP, High Pass Filter
-    // 0x20 = BP, Band Pass Filter
-    // 0x30 = NP, Notch or Band Elimination Filter
-    //
-    private int filtertype = FILTERTYPE_LP6;
-    private float samplerate;
-    private float x1;
-    private float x2;
-    private float y1;
-    private float y2;
-    private float xx1;
-    private float xx2;
-    private float yy1;
-    private float yy2;
-    private float a0;
-    private float a1;
-    private float a2;
-    private float b1;
-    private float b2;
-    private float q;
-    private float gain = 1;
-    private float wet = 0;
-    private float last_wet = 0;
-    private float last_a0;
-    private float last_a1;
-    private float last_a2;
-    private float last_b1;
-    private float last_b2;
-    private float last_q;
-    private float last_gain;
-    private boolean last_set = false;
-    private double cutoff = 44100;
-    private double resonancedB = 0;
-    private boolean dirty = true;
-
-    public SoftFilter(float samplerate) {
-        this.samplerate = samplerate;
-        dirty = true;
-    }
-
-    public void setFrequency(double cent) {
-        if (cutoff == cent)
-            return;
-        cutoff = cent;
-        dirty = true;
-    }
-
-    public void setResonance(double db) {
-        if (resonancedB == db)
-            return;
-        resonancedB = db;
-        dirty = true;
-    }
-
-    public void reset() {
-        dirty = true;
-        last_set = false;
-        x1 = 0;
-        x2 = 0;
-        y1 = 0;
-        y2 = 0;
-        xx1 = 0;
-        xx2 = 0;
-        yy1 = 0;
-        yy2 = 0;
-        wet = 0.0f;
-        gain = 1.0f;
-        a0 = 0;
-        a1 = 0;
-        a2 = 0;
-        b1 = 0;
-        b2 = 0;
-    }
-
-    public void setFilterType(int filtertype) {
-        this.filtertype = filtertype;
-    }
-
-    public void processAudio(SoftAudioBuffer sbuffer) {
-        if (filtertype == FILTERTYPE_LP6)
-            filter1(sbuffer);
-        if (filtertype == FILTERTYPE_LP12)
-            filter2(sbuffer);
-        if (filtertype == FILTERTYPE_HP12)
-            filter2(sbuffer);
-        if (filtertype == FILTERTYPE_BP12)
-            filter2(sbuffer);
-        if (filtertype == FILTERTYPE_NP12)
-            filter2(sbuffer);
-        if (filtertype == FILTERTYPE_LP24)
-            filter4(sbuffer);
-        if (filtertype == FILTERTYPE_HP24)
-            filter4(sbuffer);
-    }
-
-    public void filter4(SoftAudioBuffer sbuffer) {
-
-        float[] buffer = sbuffer.array();
-
-        if (dirty) {
-            filter2calc();
-            dirty = false;
-        }
-        if (!last_set) {
-            last_a0 = a0;
-            last_a1 = a1;
-            last_a2 = a2;
-            last_b1 = b1;
-            last_b2 = b2;
-            last_gain = gain;
-            last_wet = wet;
-            last_set = true;
-        }
-
-        if (wet > 0 || last_wet > 0) {
-
-            int len = buffer.length;
-            float a0 = this.last_a0;
-            float a1 = this.last_a1;
-            float a2 = this.last_a2;
-            float b1 = this.last_b1;
-            float b2 = this.last_b2;
-            float gain = this.last_gain;
-            float wet = this.last_wet;
-            float a0_delta = (this.a0 - this.last_a0) / len;
-            float a1_delta = (this.a1 - this.last_a1) / len;
-            float a2_delta = (this.a2 - this.last_a2) / len;
-            float b1_delta = (this.b1 - this.last_b1) / len;
-            float b2_delta = (this.b2 - this.last_b2) / len;
-            float gain_delta = (this.gain - this.last_gain) / len;
-            float wet_delta = (this.wet - this.last_wet) / len;
-            float x1 = this.x1;
-            float x2 = this.x2;
-            float y1 = this.y1;
-            float y2 = this.y2;
-            float xx1 = this.xx1;
-            float xx2 = this.xx2;
-            float yy1 = this.yy1;
-            float yy2 = this.yy2;
-
-            if (wet_delta != 0) {
-                for (int i = 0; i < len; i++) {
-                    a0 += a0_delta;
-                    a1 += a1_delta;
-                    a2 += a2_delta;
-                    b1 += b1_delta;
-                    b2 += b2_delta;
-                    gain += gain_delta;
-                    wet += wet_delta;
-                    float x = buffer[i];
-                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
-                    float xx = (y * gain) * wet + (x) * (1 - wet);
-                    x2 = x1;
-                    x1 = x;
-                    y2 = y1;
-                    y1 = y;
-                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
-                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
-                    xx2 = xx1;
-                    xx1 = xx;
-                    yy2 = yy1;
-                    yy1 = yy;
-                }
-            } else if (a0_delta == 0 && a1_delta == 0 && a2_delta == 0
-                    && b1_delta == 0 && b2_delta == 0) {
-                for (int i = 0; i < len; i++) {
-                    float x = buffer[i];
-                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
-                    float xx = (y * gain) * wet + (x) * (1 - wet);
-                    x2 = x1;
-                    x1 = x;
-                    y2 = y1;
-                    y1 = y;
-                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
-                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
-                    xx2 = xx1;
-                    xx1 = xx;
-                    yy2 = yy1;
-                    yy1 = yy;
-                }
-            } else {
-                for (int i = 0; i < len; i++) {
-                    a0 += a0_delta;
-                    a1 += a1_delta;
-                    a2 += a2_delta;
-                    b1 += b1_delta;
-                    b2 += b2_delta;
-                    gain += gain_delta;
-                    float x = buffer[i];
-                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
-                    float xx = (y * gain) * wet + (x) * (1 - wet);
-                    x2 = x1;
-                    x1 = x;
-                    y2 = y1;
-                    y1 = y;
-                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
-                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
-                    xx2 = xx1;
-                    xx1 = xx;
-                    yy2 = yy1;
-                    yy1 = yy;
-                }
-            }
-
-            if (Math.abs(x1) < 1.0E-8)
-                x1 = 0;
-            if (Math.abs(x2) < 1.0E-8)
-                x2 = 0;
-            if (Math.abs(y1) < 1.0E-8)
-                y1 = 0;
-            if (Math.abs(y2) < 1.0E-8)
-                y2 = 0;
-            this.x1 = x1;
-            this.x2 = x2;
-            this.y1 = y1;
-            this.y2 = y2;
-            this.xx1 = xx1;
-            this.xx2 = xx2;
-            this.yy1 = yy1;
-            this.yy2 = yy2;
-        }
-
-        this.last_a0 = this.a0;
-        this.last_a1 = this.a1;
-        this.last_a2 = this.a2;
-        this.last_b1 = this.b1;
-        this.last_b2 = this.b2;
-        this.last_gain = this.gain;
-        this.last_wet = this.wet;
-
-    }
-
-    private double sinh(double x) {
-        return (Math.exp(x) - Math.exp(-x)) * 0.5;
-    }
-
-    public void filter2calc() {
-
-        double resonancedB = this.resonancedB;
-        if (resonancedB < 0)
-            resonancedB = 0;    // Negative dB are illegal.
-        if (resonancedB > 30)
-            resonancedB = 30;   // At least 22.5 dB is needed.
-        if (filtertype == FILTERTYPE_LP24 || filtertype == FILTERTYPE_HP24)
-            resonancedB *= 0.6;
-
-        if (filtertype == FILTERTYPE_BP12) {
-            wet = 1;
-            double r = (cutoff / samplerate);
-            if (r > 0.45)
-                r = 0.45;
-
-            double bandwidth = Math.PI * Math.pow(10.0, -(resonancedB / 20));
-
-            double omega = 2 * Math.PI * r;
-            double cs = Math.cos(omega);
-            double sn = Math.sin(omega);
-            double alpha = sn * sinh((Math.log(2)*bandwidth*omega) / (sn * 2));
-
-            double b0 = alpha;
-            double b1 = 0;
-            double b2 = -alpha;
-            double a0 = 1 + alpha;
-            double a1 = -2 * cs;
-            double a2 = 1 - alpha;
-
-            double cf = 1.0 / a0;
-            this.b1 = (float) (a1 * cf);
-            this.b2 = (float) (a2 * cf);
-            this.a0 = (float) (b0 * cf);
-            this.a1 = (float) (b1 * cf);
-            this.a2 = (float) (b2 * cf);
-        }
-
-        if (filtertype == FILTERTYPE_NP12) {
-            wet = 1;
-            double r = (cutoff / samplerate);
-            if (r > 0.45)
-                r = 0.45;
-
-            double bandwidth = Math.PI * Math.pow(10.0, -(resonancedB / 20));
-
-            double omega = 2 * Math.PI * r;
-            double cs = Math.cos(omega);
-            double sn = Math.sin(omega);
-            double alpha = sn * sinh((Math.log(2)*bandwidth*omega) / (sn*2));
-
-            double b0 = 1;
-            double b1 = -2 * cs;
-            double b2 = 1;
-            double a0 = 1 + alpha;
-            double a1 = -2 * cs;
-            double a2 = 1 - alpha;
-
-            double cf = 1.0 / a0;
-            this.b1 = (float)(a1 * cf);
-            this.b2 = (float)(a2 * cf);
-            this.a0 = (float)(b0 * cf);
-            this.a1 = (float)(b1 * cf);
-            this.a2 = (float)(b2 * cf);
-        }
-
-        if (filtertype == FILTERTYPE_LP12 || filtertype == FILTERTYPE_LP24) {
-            double r = (cutoff / samplerate);
-            if (r > 0.45) {
-                if (wet == 0) {
-                    if (resonancedB < 0.00001)
-                        wet = 0.0f;
-                    else
-                        wet = 1.0f;
-                }
-                r = 0.45;
-            } else
-                wet = 1.0f;
-
-            double c = 1.0 / (Math.tan(Math.PI * r));
-            double csq = c * c;
-            double resonance = Math.pow(10.0, -(resonancedB / 20));
-            double q = Math.sqrt(2.0f) * resonance;
-            double a0 = 1.0 / (1.0 + (q * c) + (csq));
-            double a1 = 2.0 * a0;
-            double a2 = a0;
-            double b1 = (2.0 * a0) * (1.0 - csq);
-            double b2 = a0 * (1.0 - (q * c) + csq);
-
-            this.a0 = (float)a0;
-            this.a1 = (float)a1;
-            this.a2 = (float)a2;
-            this.b1 = (float)b1;
-            this.b2 = (float)b2;
-
-        }
-
-        if (filtertype == FILTERTYPE_HP12 || filtertype == FILTERTYPE_HP24) {
-            double r = (cutoff / samplerate);
-            if (r > 0.45)
-                r = 0.45;
-            if (r < 0.0001)
-                r = 0.0001;
-            wet = 1.0f;
-            double c = (Math.tan(Math.PI * (r)));
-            double csq = c * c;
-            double resonance = Math.pow(10.0, -(resonancedB / 20));
-            double q = Math.sqrt(2.0f) * resonance;
-            double a0 = 1.0 / (1.0 + (q * c) + (csq));
-            double a1 = -2.0 * a0;
-            double a2 = a0;
-            double b1 = (2.0 * a0) * (csq - 1.0);
-            double b2 = a0 * (1.0 - (q * c) + csq);
-
-            this.a0 = (float)a0;
-            this.a1 = (float)a1;
-            this.a2 = (float)a2;
-            this.b1 = (float)b1;
-            this.b2 = (float)b2;
-
-        }
-
-    }
-
-    public void filter2(SoftAudioBuffer sbuffer) {
-
-        float[] buffer = sbuffer.array();
-
-        if (dirty) {
-            filter2calc();
-            dirty = false;
-        }
-        if (!last_set) {
-            last_a0 = a0;
-            last_a1 = a1;
-            last_a2 = a2;
-            last_b1 = b1;
-            last_b2 = b2;
-            last_q = q;
-            last_gain = gain;
-            last_wet = wet;
-            last_set = true;
-        }
-
-        if (wet > 0 || last_wet > 0) {
-
-            int len = buffer.length;
-            float a0 = this.last_a0;
-            float a1 = this.last_a1;
-            float a2 = this.last_a2;
-            float b1 = this.last_b1;
-            float b2 = this.last_b2;
-            float gain = this.last_gain;
-            float wet = this.last_wet;
-            float a0_delta = (this.a0 - this.last_a0) / len;
-            float a1_delta = (this.a1 - this.last_a1) / len;
-            float a2_delta = (this.a2 - this.last_a2) / len;
-            float b1_delta = (this.b1 - this.last_b1) / len;
-            float b2_delta = (this.b2 - this.last_b2) / len;
-            float gain_delta = (this.gain - this.last_gain) / len;
-            float wet_delta = (this.wet - this.last_wet) / len;
-            float x1 = this.x1;
-            float x2 = this.x2;
-            float y1 = this.y1;
-            float y2 = this.y2;
-
-            if (wet_delta != 0) {
-                for (int i = 0; i < len; i++) {
-                    a0 += a0_delta;
-                    a1 += a1_delta;
-                    a2 += a2_delta;
-                    b1 += b1_delta;
-                    b2 += b2_delta;
-                    gain += gain_delta;
-                    wet += wet_delta;
-                    float x = buffer[i];
-                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
-                    buffer[i] = (y * gain) * wet + (x) * (1 - wet);
-                    x2 = x1;
-                    x1 = x;
-                    y2 = y1;
-                    y1 = y;
-                }
-            } else if (a0_delta == 0 && a1_delta == 0 && a2_delta == 0
-                    && b1_delta == 0 && b2_delta == 0) {
-                for (int i = 0; i < len; i++) {
-                    float x = buffer[i];
-                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
-                    buffer[i] = y * gain;
-                    x2 = x1;
-                    x1 = x;
-                    y2 = y1;
-                    y1 = y;
-                }
-            } else {
-                for (int i = 0; i < len; i++) {
-                    a0 += a0_delta;
-                    a1 += a1_delta;
-                    a2 += a2_delta;
-                    b1 += b1_delta;
-                    b2 += b2_delta;
-                    gain += gain_delta;
-                    float x = buffer[i];
-                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
-                    buffer[i] = y * gain;
-                    x2 = x1;
-                    x1 = x;
-                    y2 = y1;
-                    y1 = y;
-                }
-            }
-
-            if (Math.abs(x1) < 1.0E-8)
-                x1 = 0;
-            if (Math.abs(x2) < 1.0E-8)
-                x2 = 0;
-            if (Math.abs(y1) < 1.0E-8)
-                y1 = 0;
-            if (Math.abs(y2) < 1.0E-8)
-                y2 = 0;
-            this.x1 = x1;
-            this.x2 = x2;
-            this.y1 = y1;
-            this.y2 = y2;
-        }
-
-        this.last_a0 = this.a0;
-        this.last_a1 = this.a1;
-        this.last_a2 = this.a2;
-        this.last_b1 = this.b1;
-        this.last_b2 = this.b2;
-        this.last_q = this.q;
-        this.last_gain = this.gain;
-        this.last_wet = this.wet;
-
-    }
-
-    public void filter1calc() {
-        if (cutoff < 120)
-            cutoff = 120;
-        double c = (7.0 / 6.0) * Math.PI * 2 * cutoff / samplerate;
-        if (c > 1)
-            c = 1;
-        a0 = (float)(Math.sqrt(1 - Math.cos(c)) * Math.sqrt(0.5 * Math.PI));
-        if (resonancedB < 0)
-            resonancedB = 0;
-        if (resonancedB > 20)
-            resonancedB = 20;
-        q = (float)(Math.sqrt(0.5) * Math.pow(10.0, -(resonancedB / 20)));
-        gain = (float)Math.pow(10, -((resonancedB)) / 40.0);
-        if (wet == 0.0f)
-            if (resonancedB > 0.00001 || c < 0.9999999)
-                wet = 1.0f;
-    }
-
-    public void filter1(SoftAudioBuffer sbuffer) {
-
-        float[] buffer = sbuffer.array();
-
-        if (dirty) {
-            filter1calc();
-            dirty = false;
-        }
-        if (!last_set) {
-            last_a0 = a0;
-            last_q = q;
-            last_gain = gain;
-            last_wet = wet;
-            last_set = true;
-        }
-
-        if (wet > 0 || last_wet > 0) {
-
-            int len = buffer.length;
-            float a0 = this.last_a0;
-            float q = this.last_q;
-            float gain = this.last_gain;
-            float wet = this.last_wet;
-            float a0_delta = (this.a0 - this.last_a0) / len;
-            float q_delta = (this.q - this.last_q) / len;
-            float gain_delta = (this.gain - this.last_gain) / len;
-            float wet_delta = (this.wet - this.last_wet) / len;
-            float y2 = this.y2;
-            float y1 = this.y1;
-
-            if (wet_delta != 0) {
-                for (int i = 0; i < len; i++) {
-                    a0 += a0_delta;
-                    q += q_delta;
-                    gain += gain_delta;
-                    wet += wet_delta;
-                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
-                    y2 = (1 - q * a0) * y2 + (a0) * y1;
-                    buffer[i] = y2 * gain * wet + buffer[i] * (1 - wet);
-                }
-            } else if (a0_delta == 0 && q_delta == 0) {
-                for (int i = 0; i < len; i++) {
-                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
-                    y2 = (1 - q * a0) * y2 + (a0) * y1;
-                    buffer[i] = y2 * gain;
-                }
-            } else {
-                for (int i = 0; i < len; i++) {
-                    a0 += a0_delta;
-                    q += q_delta;
-                    gain += gain_delta;
-                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
-                    y2 = (1 - q * a0) * y2 + (a0) * y1;
-                    buffer[i] = y2 * gain;
-                }
-            }
-
-            if (Math.abs(y2) < 1.0E-8)
-                y2 = 0;
-            if (Math.abs(y1) < 1.0E-8)
-                y1 = 0;
-            this.y2 = y2;
-            this.y1 = y1;
-        }
-
-        this.last_a0 = this.a0;
-        this.last_q = this.q;
-        this.last_gain = this.gain;
-        this.last_wet = this.wet;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Infinite impulse response (IIR) filter class.
+ *
+ * The filters where implemented and adapted using algorithms from musicdsp.org
+ * archive: 1-RC and C filter, Simple 2-pole LP LP and HP filter, biquad,
+ * tweaked butterworth RBJ Audio-EQ-Cookbook, EQ filter kookbook
+ *
+ * @author Karl Helgason
+ */
+public class SoftFilter {
+
+    public static int FILTERTYPE_LP6 = 0x00;
+    public static int FILTERTYPE_LP12 = 0x01;
+    public static int FILTERTYPE_HP12 = 0x11;
+    public static int FILTERTYPE_BP12 = 0x21;
+    public static int FILTERTYPE_NP12 = 0x31;
+    public static int FILTERTYPE_LP24 = 0x03;
+    public static int FILTERTYPE_HP24 = 0x13;
+
+    //
+    // 0x0 = 1st-order, 6 dB/oct
+    // 0x1 = 2nd-order, 12 dB/oct
+    // 0x2 = 3rd-order, 18 dB/oct
+    // 0x3 = 4th-order, 24 db/oct
+    //
+    // 0x00 = LP, Low Pass Filter
+    // 0x10 = HP, High Pass Filter
+    // 0x20 = BP, Band Pass Filter
+    // 0x30 = NP, Notch or Band Elimination Filter
+    //
+    private int filtertype = FILTERTYPE_LP6;
+    private float samplerate;
+    private float x1;
+    private float x2;
+    private float y1;
+    private float y2;
+    private float xx1;
+    private float xx2;
+    private float yy1;
+    private float yy2;
+    private float a0;
+    private float a1;
+    private float a2;
+    private float b1;
+    private float b2;
+    private float q;
+    private float gain = 1;
+    private float wet = 0;
+    private float last_wet = 0;
+    private float last_a0;
+    private float last_a1;
+    private float last_a2;
+    private float last_b1;
+    private float last_b2;
+    private float last_q;
+    private float last_gain;
+    private boolean last_set = false;
+    private double cutoff = 44100;
+    private double resonancedB = 0;
+    private boolean dirty = true;
+
+    public SoftFilter(float samplerate) {
+        this.samplerate = samplerate;
+        dirty = true;
+    }
+
+    public void setFrequency(double cent) {
+        if (cutoff == cent)
+            return;
+        cutoff = cent;
+        dirty = true;
+    }
+
+    public void setResonance(double db) {
+        if (resonancedB == db)
+            return;
+        resonancedB = db;
+        dirty = true;
+    }
+
+    public void reset() {
+        dirty = true;
+        last_set = false;
+        x1 = 0;
+        x2 = 0;
+        y1 = 0;
+        y2 = 0;
+        xx1 = 0;
+        xx2 = 0;
+        yy1 = 0;
+        yy2 = 0;
+        wet = 0.0f;
+        gain = 1.0f;
+        a0 = 0;
+        a1 = 0;
+        a2 = 0;
+        b1 = 0;
+        b2 = 0;
+    }
+
+    public void setFilterType(int filtertype) {
+        this.filtertype = filtertype;
+    }
+
+    public void processAudio(SoftAudioBuffer sbuffer) {
+        if (filtertype == FILTERTYPE_LP6)
+            filter1(sbuffer);
+        if (filtertype == FILTERTYPE_LP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_HP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_BP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_NP12)
+            filter2(sbuffer);
+        if (filtertype == FILTERTYPE_LP24)
+            filter4(sbuffer);
+        if (filtertype == FILTERTYPE_HP24)
+            filter4(sbuffer);
+    }
+
+    public void filter4(SoftAudioBuffer sbuffer) {
+
+        float[] buffer = sbuffer.array();
+
+        if (dirty) {
+            filter2calc();
+            dirty = false;
+        }
+        if (!last_set) {
+            last_a0 = a0;
+            last_a1 = a1;
+            last_a2 = a2;
+            last_b1 = b1;
+            last_b2 = b2;
+            last_gain = gain;
+            last_wet = wet;
+            last_set = true;
+        }
+
+        if (wet > 0 || last_wet > 0) {
+
+            int len = buffer.length;
+            float a0 = this.last_a0;
+            float a1 = this.last_a1;
+            float a2 = this.last_a2;
+            float b1 = this.last_b1;
+            float b2 = this.last_b2;
+            float gain = this.last_gain;
+            float wet = this.last_wet;
+            float a0_delta = (this.a0 - this.last_a0) / len;
+            float a1_delta = (this.a1 - this.last_a1) / len;
+            float a2_delta = (this.a2 - this.last_a2) / len;
+            float b1_delta = (this.b1 - this.last_b1) / len;
+            float b2_delta = (this.b2 - this.last_b2) / len;
+            float gain_delta = (this.gain - this.last_gain) / len;
+            float wet_delta = (this.wet - this.last_wet) / len;
+            float x1 = this.x1;
+            float x2 = this.x2;
+            float y1 = this.y1;
+            float y2 = this.y2;
+            float xx1 = this.xx1;
+            float xx2 = this.xx2;
+            float yy1 = this.yy1;
+            float yy2 = this.yy2;
+
+            if (wet_delta != 0) {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    wet += wet_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    float xx = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
+                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
+                    xx2 = xx1;
+                    xx1 = xx;
+                    yy2 = yy1;
+                    yy1 = yy;
+                }
+            } else if (a0_delta == 0 && a1_delta == 0 && a2_delta == 0
+                    && b1_delta == 0 && b2_delta == 0) {
+                for (int i = 0; i < len; i++) {
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    float xx = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
+                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
+                    xx2 = xx1;
+                    xx1 = xx;
+                    yy2 = yy1;
+                    yy1 = yy;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    float xx = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                    float yy = (a0*xx + a1*xx1 + a2*xx2 - b1*yy1 - b2*yy2);
+                    buffer[i] = (yy * gain) * wet + (xx) * (1 - wet);
+                    xx2 = xx1;
+                    xx1 = xx;
+                    yy2 = yy1;
+                    yy1 = yy;
+                }
+            }
+
+            if (Math.abs(x1) < 1.0E-8)
+                x1 = 0;
+            if (Math.abs(x2) < 1.0E-8)
+                x2 = 0;
+            if (Math.abs(y1) < 1.0E-8)
+                y1 = 0;
+            if (Math.abs(y2) < 1.0E-8)
+                y2 = 0;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.y1 = y1;
+            this.y2 = y2;
+            this.xx1 = xx1;
+            this.xx2 = xx2;
+            this.yy1 = yy1;
+            this.yy2 = yy2;
+        }
+
+        this.last_a0 = this.a0;
+        this.last_a1 = this.a1;
+        this.last_a2 = this.a2;
+        this.last_b1 = this.b1;
+        this.last_b2 = this.b2;
+        this.last_gain = this.gain;
+        this.last_wet = this.wet;
+
+    }
+
+    private double sinh(double x) {
+        return (Math.exp(x) - Math.exp(-x)) * 0.5;
+    }
+
+    public void filter2calc() {
+
+        double resonancedB = this.resonancedB;
+        if (resonancedB < 0)
+            resonancedB = 0;    // Negative dB are illegal.
+        if (resonancedB > 30)
+            resonancedB = 30;   // At least 22.5 dB is needed.
+        if (filtertype == FILTERTYPE_LP24 || filtertype == FILTERTYPE_HP24)
+            resonancedB *= 0.6;
+
+        if (filtertype == FILTERTYPE_BP12) {
+            wet = 1;
+            double r = (cutoff / samplerate);
+            if (r > 0.45)
+                r = 0.45;
+
+            double bandwidth = Math.PI * Math.pow(10.0, -(resonancedB / 20));
+
+            double omega = 2 * Math.PI * r;
+            double cs = Math.cos(omega);
+            double sn = Math.sin(omega);
+            double alpha = sn * sinh((Math.log(2)*bandwidth*omega) / (sn * 2));
+
+            double b0 = alpha;
+            double b1 = 0;
+            double b2 = -alpha;
+            double a0 = 1 + alpha;
+            double a1 = -2 * cs;
+            double a2 = 1 - alpha;
+
+            double cf = 1.0 / a0;
+            this.b1 = (float) (a1 * cf);
+            this.b2 = (float) (a2 * cf);
+            this.a0 = (float) (b0 * cf);
+            this.a1 = (float) (b1 * cf);
+            this.a2 = (float) (b2 * cf);
+        }
+
+        if (filtertype == FILTERTYPE_NP12) {
+            wet = 1;
+            double r = (cutoff / samplerate);
+            if (r > 0.45)
+                r = 0.45;
+
+            double bandwidth = Math.PI * Math.pow(10.0, -(resonancedB / 20));
+
+            double omega = 2 * Math.PI * r;
+            double cs = Math.cos(omega);
+            double sn = Math.sin(omega);
+            double alpha = sn * sinh((Math.log(2)*bandwidth*omega) / (sn*2));
+
+            double b0 = 1;
+            double b1 = -2 * cs;
+            double b2 = 1;
+            double a0 = 1 + alpha;
+            double a1 = -2 * cs;
+            double a2 = 1 - alpha;
+
+            double cf = 1.0 / a0;
+            this.b1 = (float)(a1 * cf);
+            this.b2 = (float)(a2 * cf);
+            this.a0 = (float)(b0 * cf);
+            this.a1 = (float)(b1 * cf);
+            this.a2 = (float)(b2 * cf);
+        }
+
+        if (filtertype == FILTERTYPE_LP12 || filtertype == FILTERTYPE_LP24) {
+            double r = (cutoff / samplerate);
+            if (r > 0.45) {
+                if (wet == 0) {
+                    if (resonancedB < 0.00001)
+                        wet = 0.0f;
+                    else
+                        wet = 1.0f;
+                }
+                r = 0.45;
+            } else
+                wet = 1.0f;
+
+            double c = 1.0 / (Math.tan(Math.PI * r));
+            double csq = c * c;
+            double resonance = Math.pow(10.0, -(resonancedB / 20));
+            double q = Math.sqrt(2.0f) * resonance;
+            double a0 = 1.0 / (1.0 + (q * c) + (csq));
+            double a1 = 2.0 * a0;
+            double a2 = a0;
+            double b1 = (2.0 * a0) * (1.0 - csq);
+            double b2 = a0 * (1.0 - (q * c) + csq);
+
+            this.a0 = (float)a0;
+            this.a1 = (float)a1;
+            this.a2 = (float)a2;
+            this.b1 = (float)b1;
+            this.b2 = (float)b2;
+
+        }
+
+        if (filtertype == FILTERTYPE_HP12 || filtertype == FILTERTYPE_HP24) {
+            double r = (cutoff / samplerate);
+            if (r > 0.45)
+                r = 0.45;
+            if (r < 0.0001)
+                r = 0.0001;
+            wet = 1.0f;
+            double c = (Math.tan(Math.PI * (r)));
+            double csq = c * c;
+            double resonance = Math.pow(10.0, -(resonancedB / 20));
+            double q = Math.sqrt(2.0f) * resonance;
+            double a0 = 1.0 / (1.0 + (q * c) + (csq));
+            double a1 = -2.0 * a0;
+            double a2 = a0;
+            double b1 = (2.0 * a0) * (csq - 1.0);
+            double b2 = a0 * (1.0 - (q * c) + csq);
+
+            this.a0 = (float)a0;
+            this.a1 = (float)a1;
+            this.a2 = (float)a2;
+            this.b1 = (float)b1;
+            this.b2 = (float)b2;
+
+        }
+
+    }
+
+    public void filter2(SoftAudioBuffer sbuffer) {
+
+        float[] buffer = sbuffer.array();
+
+        if (dirty) {
+            filter2calc();
+            dirty = false;
+        }
+        if (!last_set) {
+            last_a0 = a0;
+            last_a1 = a1;
+            last_a2 = a2;
+            last_b1 = b1;
+            last_b2 = b2;
+            last_q = q;
+            last_gain = gain;
+            last_wet = wet;
+            last_set = true;
+        }
+
+        if (wet > 0 || last_wet > 0) {
+
+            int len = buffer.length;
+            float a0 = this.last_a0;
+            float a1 = this.last_a1;
+            float a2 = this.last_a2;
+            float b1 = this.last_b1;
+            float b2 = this.last_b2;
+            float gain = this.last_gain;
+            float wet = this.last_wet;
+            float a0_delta = (this.a0 - this.last_a0) / len;
+            float a1_delta = (this.a1 - this.last_a1) / len;
+            float a2_delta = (this.a2 - this.last_a2) / len;
+            float b1_delta = (this.b1 - this.last_b1) / len;
+            float b2_delta = (this.b2 - this.last_b2) / len;
+            float gain_delta = (this.gain - this.last_gain) / len;
+            float wet_delta = (this.wet - this.last_wet) / len;
+            float x1 = this.x1;
+            float x2 = this.x2;
+            float y1 = this.y1;
+            float y2 = this.y2;
+
+            if (wet_delta != 0) {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    wet += wet_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    buffer[i] = (y * gain) * wet + (x) * (1 - wet);
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                }
+            } else if (a0_delta == 0 && a1_delta == 0 && a2_delta == 0
+                    && b1_delta == 0 && b2_delta == 0) {
+                for (int i = 0; i < len; i++) {
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    buffer[i] = y * gain;
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    a1 += a1_delta;
+                    a2 += a2_delta;
+                    b1 += b1_delta;
+                    b2 += b2_delta;
+                    gain += gain_delta;
+                    float x = buffer[i];
+                    float y = (a0*x + a1*x1 + a2*x2 - b1*y1 - b2*y2);
+                    buffer[i] = y * gain;
+                    x2 = x1;
+                    x1 = x;
+                    y2 = y1;
+                    y1 = y;
+                }
+            }
+
+            if (Math.abs(x1) < 1.0E-8)
+                x1 = 0;
+            if (Math.abs(x2) < 1.0E-8)
+                x2 = 0;
+            if (Math.abs(y1) < 1.0E-8)
+                y1 = 0;
+            if (Math.abs(y2) < 1.0E-8)
+                y2 = 0;
+            this.x1 = x1;
+            this.x2 = x2;
+            this.y1 = y1;
+            this.y2 = y2;
+        }
+
+        this.last_a0 = this.a0;
+        this.last_a1 = this.a1;
+        this.last_a2 = this.a2;
+        this.last_b1 = this.b1;
+        this.last_b2 = this.b2;
+        this.last_q = this.q;
+        this.last_gain = this.gain;
+        this.last_wet = this.wet;
+
+    }
+
+    public void filter1calc() {
+        if (cutoff < 120)
+            cutoff = 120;
+        double c = (7.0 / 6.0) * Math.PI * 2 * cutoff / samplerate;
+        if (c > 1)
+            c = 1;
+        a0 = (float)(Math.sqrt(1 - Math.cos(c)) * Math.sqrt(0.5 * Math.PI));
+        if (resonancedB < 0)
+            resonancedB = 0;
+        if (resonancedB > 20)
+            resonancedB = 20;
+        q = (float)(Math.sqrt(0.5) * Math.pow(10.0, -(resonancedB / 20)));
+        gain = (float)Math.pow(10, -((resonancedB)) / 40.0);
+        if (wet == 0.0f)
+            if (resonancedB > 0.00001 || c < 0.9999999)
+                wet = 1.0f;
+    }
+
+    public void filter1(SoftAudioBuffer sbuffer) {
+
+        float[] buffer = sbuffer.array();
+
+        if (dirty) {
+            filter1calc();
+            dirty = false;
+        }
+        if (!last_set) {
+            last_a0 = a0;
+            last_q = q;
+            last_gain = gain;
+            last_wet = wet;
+            last_set = true;
+        }
+
+        if (wet > 0 || last_wet > 0) {
+
+            int len = buffer.length;
+            float a0 = this.last_a0;
+            float q = this.last_q;
+            float gain = this.last_gain;
+            float wet = this.last_wet;
+            float a0_delta = (this.a0 - this.last_a0) / len;
+            float q_delta = (this.q - this.last_q) / len;
+            float gain_delta = (this.gain - this.last_gain) / len;
+            float wet_delta = (this.wet - this.last_wet) / len;
+            float y2 = this.y2;
+            float y1 = this.y1;
+
+            if (wet_delta != 0) {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    q += q_delta;
+                    gain += gain_delta;
+                    wet += wet_delta;
+                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
+                    y2 = (1 - q * a0) * y2 + (a0) * y1;
+                    buffer[i] = y2 * gain * wet + buffer[i] * (1 - wet);
+                }
+            } else if (a0_delta == 0 && q_delta == 0) {
+                for (int i = 0; i < len; i++) {
+                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
+                    y2 = (1 - q * a0) * y2 + (a0) * y1;
+                    buffer[i] = y2 * gain;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    a0 += a0_delta;
+                    q += q_delta;
+                    gain += gain_delta;
+                    y1 = (1 - q * a0) * y1 - (a0) * y2 + (a0) * buffer[i];
+                    y2 = (1 - q * a0) * y2 + (a0) * y1;
+                    buffer[i] = y2 * gain;
+                }
+            }
+
+            if (Math.abs(y2) < 1.0E-8)
+                y2 = 0;
+            if (Math.abs(y1) < 1.0E-8)
+                y1 = 0;
+            this.y2 = y2;
+            this.y1 = y1;
+        }
+
+        this.last_a0 = this.a0;
+        this.last_q = this.q;
+        this.last_gain = this.gain;
+        this.last_wet = this.wet;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftInstrument.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftInstrument.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,90 +1,90 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.Instrument;
-import javax.sound.midi.MidiChannel;
-
-/**
- * Software synthesizer internal instrument.
- *
- * @author Karl Helgason
- */
-public class SoftInstrument extends Instrument {
-
-    private SoftPerformer[] performers;
-    private ModelPerformer[] modelperformers;
-    private Object data;
-    private ModelInstrument ins;
-
-    public SoftInstrument(ModelInstrument ins) {
-        super(ins.getSoundbank(), ins.getPatch(), ins.getName(),
-                ins.getDataClass());
-        if (!(ins instanceof ModelInstrument)) {
-            throw new IllegalArgumentException(
-                    "Instrument doesn't implement ModelInstrument interface!");
-        }
-        data = ins.getData();
-        this.ins = ins;
-        initPerformers(((ModelInstrument)ins).getPerformers());
-    }
-
-    public SoftInstrument(ModelInstrument ins,
-            ModelPerformer[] overrideperformers) {
-        super(ins.getSoundbank(), ins.getPatch(), ins.getName(),
-                ins.getDataClass());
-        if (!(ins instanceof ModelInstrument)) {
-            throw new IllegalArgumentException(
-                    "Instrument doesn't implement ModelInstrument interface!");
-        }
-        data = ins.getData();
-        this.ins = ins;
-        initPerformers(overrideperformers);
-    }
-
-    private void initPerformers(ModelPerformer[] modelperformers) {
-        this.modelperformers = modelperformers;
-        performers = new SoftPerformer[modelperformers.length];
-        for (int i = 0; i < modelperformers.length; i++)
-            performers[i] = new SoftPerformer(modelperformers[i]);
-    }
-
-    public ModelDirector getDirector(MidiChannel channel,
-            ModelDirectedPlayer player) {
-        return ins.getDirector(modelperformers, channel, player);
-    }
-
-    public ModelInstrument getSourceInstrument() {
-        return ins;
-    }
-
-    public Object getData() {
-        return data;
-    }
-
-    public SoftPerformer[] getPerformers() {
-        return performers;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+
+/**
+ * Software synthesizer internal instrument.
+ *
+ * @author Karl Helgason
+ */
+public class SoftInstrument extends Instrument {
+
+    private SoftPerformer[] performers;
+    private ModelPerformer[] modelperformers;
+    private Object data;
+    private ModelInstrument ins;
+
+    public SoftInstrument(ModelInstrument ins) {
+        super(ins.getSoundbank(), ins.getPatch(), ins.getName(),
+                ins.getDataClass());
+        if (!(ins instanceof ModelInstrument)) {
+            throw new IllegalArgumentException(
+                    "Instrument doesn't implement ModelInstrument interface!");
+        }
+        data = ins.getData();
+        this.ins = ins;
+        initPerformers(((ModelInstrument)ins).getPerformers());
+    }
+
+    public SoftInstrument(ModelInstrument ins,
+            ModelPerformer[] overrideperformers) {
+        super(ins.getSoundbank(), ins.getPatch(), ins.getName(),
+                ins.getDataClass());
+        if (!(ins instanceof ModelInstrument)) {
+            throw new IllegalArgumentException(
+                    "Instrument doesn't implement ModelInstrument interface!");
+        }
+        data = ins.getData();
+        this.ins = ins;
+        initPerformers(overrideperformers);
+    }
+
+    private void initPerformers(ModelPerformer[] modelperformers) {
+        this.modelperformers = modelperformers;
+        performers = new SoftPerformer[modelperformers.length];
+        for (int i = 0; i < modelperformers.length; i++)
+            performers[i] = new SoftPerformer(modelperformers[i]);
+    }
+
+    public ModelDirector getDirector(MidiChannel channel,
+            ModelDirectedPlayer player) {
+        return ins.getDirector(modelperformers, channel, player);
+    }
+
+    public ModelInstrument getSourceInstrument() {
+        return ins;
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public SoftPerformer[] getPerformers() {
+        return performers;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftJitterCorrector.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,267 +1,267 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-
-/**
- * A jitter corrector to be used with SoftAudioPusher.
- *
- * @author Karl Helgason
- */
-public class SoftJitterCorrector extends AudioInputStream {
-
-    private static class JitterStream extends InputStream {
-
-        static int MAX_BUFFER_SIZE = 1048576;
-        boolean active = true;
-        Thread thread;
-        AudioInputStream stream;
-        // Cyclic buffer
-        int writepos = 0;
-        int readpos = 0;
-        byte[][] buffers;
-        byte[] nullbuff;
-
-        // Adapative Drift Statistics
-        int w_count = 1000;
-        int w_min_tol = 2;
-        int w_max_tol = 10;
-        int w = 0;
-        int w_min = -1;
-        // Current read buffer
-        int bbuffer_pos = 0;
-        int bbuffer_max = 0;
-        byte[] bbuffer = null;
-
-        public byte[] nextReadBuffer() {
-            synchronized (buffers) {
-                if (writepos > readpos) {
-                    int w_m = writepos - readpos;
-                    if (w_m < w_min)
-                        w_min = w_m;
-
-                    int buffpos = readpos;
-                    readpos++;
-                    return buffers[buffpos % buffers.length];
-                }
-                w_min = -1;
-                w = w_count - 1;
-            }
-            while (true) {
-                try {
-                    Thread.sleep(1);
-                } catch (InterruptedException e) {
-                    //e.printStackTrace();
-                    return null;
-                }
-                synchronized (buffers) {
-                    if (writepos > readpos) {
-                        w = 0;
-                        w_min = -1;
-                        w = w_count - 1;
-                        int buffpos = readpos;
-                        readpos++;
-                        return buffers[buffpos % buffers.length];
-                    }
-                }
-            }
-        }
-
-        public byte[] nextWriteBuffer() {
-            synchronized (buffers) {
-                return buffers[writepos % buffers.length];
-            }
-        }
-
-        public void commit() {
-            synchronized (buffers) {
-                writepos++;
-                if ((writepos - readpos) > buffers.length) {
-                    int newsize = (writepos - readpos) + 10;
-                    newsize = Math.max(buffers.length * 2, newsize);
-                    buffers = new byte[newsize][buffers[0].length];
-                }
-            }
-        }
-
-        public JitterStream(AudioInputStream s, int buffersize,
-                int smallbuffersize) {
-            this.w_count = 10 * (buffersize / smallbuffersize);
-            if (w_count < 100)
-                w_count = 100;
-            this.buffers
-                    = new byte[(buffersize/smallbuffersize)+10][smallbuffersize];
-            this.bbuffer_max = MAX_BUFFER_SIZE / smallbuffersize;
-            this.nullbuff = new byte[smallbuffersize];
-            this.stream = s;
-
-
-            Runnable runnable = new Runnable() {
-
-                public void run() {
-                    AudioFormat format = stream.getFormat();
-                    int bufflen = buffers[0].length;
-                    int frames = bufflen / format.getFrameSize();
-                    long nanos = (long) (frames * 1000000000.0
-                                            / format.getSampleRate());
-                    long now = System.nanoTime();
-                    long next = now + nanos;
-                    int correction = 0;
-                    while (true) {
-                        synchronized (JitterStream.this) {
-                            if (!active)
-                                break;
-                        }
-                        int curbuffsize;
-                        synchronized (buffers) {
-                            curbuffsize = writepos - readpos;
-                            if (correction == 0) {
-                                w++;
-                                if (w_min != Integer.MAX_VALUE) {
-                                    if (w == w_count) {
-                                        correction = 0;
-                                        if (w_min < w_min_tol) {
-                                            correction = (w_min_tol + w_max_tol)
-                                                            / 2 - w_min;
-                                        }
-                                        if (w_min > w_max_tol) {
-                                            correction = (w_min_tol + w_max_tol)
-                                                            / 2 - w_min;
-                                        }
-                                        w = 0;
-                                        w_min = Integer.MAX_VALUE;
-                                    }
-                                }
-                            }
-                        }
-                        while (curbuffsize > bbuffer_max) {
-                            synchronized (buffers) {
-                                curbuffsize = writepos - readpos;
-                            }
-                            synchronized (JitterStream.this) {
-                                if (!active)
-                                    break;
-                            }
-                            try {
-                                Thread.sleep(1);
-                            } catch (InterruptedException e) {
-                                //e.printStackTrace();
-                            }
-                        }
-
-                        if (correction < 0)
-                            correction++;
-                        else {
-                            byte[] buff = nextWriteBuffer();
-                            try {
-                                stream.read(buff, 0, buff.length);
-                            } catch (IOException e1) {
-                                //e1.printStackTrace();
-                            }
-                            commit();
-                        }
-
-                        if (correction > 0) {
-                            correction--;
-                            next = System.nanoTime() + nanos;
-                            continue;
-                        }
-                        long wait = next - System.nanoTime();
-                        if (wait > 0) {
-                            try {
-                                Thread.sleep(wait / 1000000L);
-                            } catch (InterruptedException e) {
-                                //e.printStackTrace();
-                            }
-                        }
-                        next += nanos;
-                    }
-                }
-            };
-
-            thread = new Thread(runnable);
-            thread.setPriority(Thread.MAX_PRIORITY);
-            thread.start();
-        }
-
-        public void close() throws IOException {
-            synchronized (this) {
-                active = false;
-            }
-            try {
-                thread.join();
-            } catch (InterruptedException e) {
-                //e.printStackTrace();
-            }
-            stream.close();
-        }
-
-        public int read() throws IOException {
-            byte[] b = new byte[1];
-            if (read(b) == -1)
-                return -1;
-            return b[0] & 0xFF;
-        }
-
-        public void fillBuffer() {
-            bbuffer = nextReadBuffer();
-            bbuffer_pos = 0;
-        }
-
-        public int read(byte[] b, int off, int len) {
-            if (bbuffer == null)
-                fillBuffer();
-            int bbuffer_len = bbuffer.length;
-            int offlen = off + len;
-            while (off < offlen) {
-                if (available() == 0)
-                    fillBuffer();
-                else {
-                    byte[] bbuffer = this.bbuffer;
-                    int bbuffer_pos = this.bbuffer_pos;
-                    while (off < offlen && bbuffer_pos < bbuffer_len)
-                        b[off++] = bbuffer[bbuffer_pos++];
-                    this.bbuffer_pos = bbuffer_pos;
-                }
-            }
-            return len;
-        }
-
-        public int available() {
-            return bbuffer.length - bbuffer_pos;
-        }
-    }
-
-    public SoftJitterCorrector(AudioInputStream stream, int buffersize,
-            int smallbuffersize) {
-        super(new JitterStream(stream, buffersize, smallbuffersize),
-                stream.getFormat(), stream.getFrameLength());
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+
+/**
+ * A jitter corrector to be used with SoftAudioPusher.
+ *
+ * @author Karl Helgason
+ */
+public class SoftJitterCorrector extends AudioInputStream {
+
+    private static class JitterStream extends InputStream {
+
+        static int MAX_BUFFER_SIZE = 1048576;
+        boolean active = true;
+        Thread thread;
+        AudioInputStream stream;
+        // Cyclic buffer
+        int writepos = 0;
+        int readpos = 0;
+        byte[][] buffers;
+        byte[] nullbuff;
+
+        // Adapative Drift Statistics
+        int w_count = 1000;
+        int w_min_tol = 2;
+        int w_max_tol = 10;
+        int w = 0;
+        int w_min = -1;
+        // Current read buffer
+        int bbuffer_pos = 0;
+        int bbuffer_max = 0;
+        byte[] bbuffer = null;
+
+        public byte[] nextReadBuffer() {
+            synchronized (buffers) {
+                if (writepos > readpos) {
+                    int w_m = writepos - readpos;
+                    if (w_m < w_min)
+                        w_min = w_m;
+
+                    int buffpos = readpos;
+                    readpos++;
+                    return buffers[buffpos % buffers.length];
+                }
+                w_min = -1;
+                w = w_count - 1;
+            }
+            while (true) {
+                try {
+                    Thread.sleep(1);
+                } catch (InterruptedException e) {
+                    //e.printStackTrace();
+                    return null;
+                }
+                synchronized (buffers) {
+                    if (writepos > readpos) {
+                        w = 0;
+                        w_min = -1;
+                        w = w_count - 1;
+                        int buffpos = readpos;
+                        readpos++;
+                        return buffers[buffpos % buffers.length];
+                    }
+                }
+            }
+        }
+
+        public byte[] nextWriteBuffer() {
+            synchronized (buffers) {
+                return buffers[writepos % buffers.length];
+            }
+        }
+
+        public void commit() {
+            synchronized (buffers) {
+                writepos++;
+                if ((writepos - readpos) > buffers.length) {
+                    int newsize = (writepos - readpos) + 10;
+                    newsize = Math.max(buffers.length * 2, newsize);
+                    buffers = new byte[newsize][buffers[0].length];
+                }
+            }
+        }
+
+        public JitterStream(AudioInputStream s, int buffersize,
+                int smallbuffersize) {
+            this.w_count = 10 * (buffersize / smallbuffersize);
+            if (w_count < 100)
+                w_count = 100;
+            this.buffers
+                    = new byte[(buffersize/smallbuffersize)+10][smallbuffersize];
+            this.bbuffer_max = MAX_BUFFER_SIZE / smallbuffersize;
+            this.nullbuff = new byte[smallbuffersize];
+            this.stream = s;
+
+
+            Runnable runnable = new Runnable() {
+
+                public void run() {
+                    AudioFormat format = stream.getFormat();
+                    int bufflen = buffers[0].length;
+                    int frames = bufflen / format.getFrameSize();
+                    long nanos = (long) (frames * 1000000000.0
+                                            / format.getSampleRate());
+                    long now = System.nanoTime();
+                    long next = now + nanos;
+                    int correction = 0;
+                    while (true) {
+                        synchronized (JitterStream.this) {
+                            if (!active)
+                                break;
+                        }
+                        int curbuffsize;
+                        synchronized (buffers) {
+                            curbuffsize = writepos - readpos;
+                            if (correction == 0) {
+                                w++;
+                                if (w_min != Integer.MAX_VALUE) {
+                                    if (w == w_count) {
+                                        correction = 0;
+                                        if (w_min < w_min_tol) {
+                                            correction = (w_min_tol + w_max_tol)
+                                                            / 2 - w_min;
+                                        }
+                                        if (w_min > w_max_tol) {
+                                            correction = (w_min_tol + w_max_tol)
+                                                            / 2 - w_min;
+                                        }
+                                        w = 0;
+                                        w_min = Integer.MAX_VALUE;
+                                    }
+                                }
+                            }
+                        }
+                        while (curbuffsize > bbuffer_max) {
+                            synchronized (buffers) {
+                                curbuffsize = writepos - readpos;
+                            }
+                            synchronized (JitterStream.this) {
+                                if (!active)
+                                    break;
+                            }
+                            try {
+                                Thread.sleep(1);
+                            } catch (InterruptedException e) {
+                                //e.printStackTrace();
+                            }
+                        }
+
+                        if (correction < 0)
+                            correction++;
+                        else {
+                            byte[] buff = nextWriteBuffer();
+                            try {
+                                stream.read(buff, 0, buff.length);
+                            } catch (IOException e1) {
+                                //e1.printStackTrace();
+                            }
+                            commit();
+                        }
+
+                        if (correction > 0) {
+                            correction--;
+                            next = System.nanoTime() + nanos;
+                            continue;
+                        }
+                        long wait = next - System.nanoTime();
+                        if (wait > 0) {
+                            try {
+                                Thread.sleep(wait / 1000000L);
+                            } catch (InterruptedException e) {
+                                //e.printStackTrace();
+                            }
+                        }
+                        next += nanos;
+                    }
+                }
+            };
+
+            thread = new Thread(runnable);
+            thread.setPriority(Thread.MAX_PRIORITY);
+            thread.start();
+        }
+
+        public void close() throws IOException {
+            synchronized (this) {
+                active = false;
+            }
+            try {
+                thread.join();
+            } catch (InterruptedException e) {
+                //e.printStackTrace();
+            }
+            stream.close();
+        }
+
+        public int read() throws IOException {
+            byte[] b = new byte[1];
+            if (read(b) == -1)
+                return -1;
+            return b[0] & 0xFF;
+        }
+
+        public void fillBuffer() {
+            bbuffer = nextReadBuffer();
+            bbuffer_pos = 0;
+        }
+
+        public int read(byte[] b, int off, int len) {
+            if (bbuffer == null)
+                fillBuffer();
+            int bbuffer_len = bbuffer.length;
+            int offlen = off + len;
+            while (off < offlen) {
+                if (available() == 0)
+                    fillBuffer();
+                else {
+                    byte[] bbuffer = this.bbuffer;
+                    int bbuffer_pos = this.bbuffer_pos;
+                    while (off < offlen && bbuffer_pos < bbuffer_len)
+                        b[off++] = bbuffer[bbuffer_pos++];
+                    this.bbuffer_pos = bbuffer_pos;
+                }
+            }
+            return len;
+        }
+
+        public int available() {
+            return bbuffer.length - bbuffer_pos;
+        }
+    }
+
+    public SoftJitterCorrector(AudioInputStream stream, int buffersize,
+            int smallbuffersize) {
+        super(new JitterStream(stream, buffersize, smallbuffersize),
+                stream.getFormat(), stream.getFrameLength());
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLanczosResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLanczosResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,119 +1,119 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Lanczos interpolation resampler.
- *
- * @author Karl Helgason
- */
-public class SoftLanczosResampler extends SoftAbstractResampler {
-
-    double[] din;
-    float[][] sinc_table;
-    int sinc_table_fsize = 2000;
-    int sinc_table_size = 5;
-    int sinc_table_center = sinc_table_size / 2;
-
-    public SoftLanczosResampler() {
-        super();
-        sinc_table = new float[sinc_table_fsize][];
-        for (int i = 0; i < sinc_table_fsize; i++) {
-            sinc_table[i] = sincTable(sinc_table_size, -i
-                            / ((float) sinc_table_fsize));
-        }
-    }
-
-    // Normalized sinc function
-    public static double sinc(double x) {
-        return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
-    }
-
-    // Generate sinc table
-    public static float[] sincTable(int size, float offset) {
-        int center = size / 2;
-        float[] w = new float[size];
-        for (int k = 0; k < size; k++) {
-            float x = (-center + k + offset);
-            if (x < -2 || x > 2)
-                w[k] = 0;
-            else if (x == 0)
-                w[k] = 1;
-            else {
-                w[k] = (float)(2.0 * Math.sin(Math.PI * x)
-                                * Math.sin(Math.PI * x / 2.0)
-                                / ((Math.PI * x) * (Math.PI * x)));
-            }
-        }
-        return w;
-    }
-
-    public int getPadding() // must be at least half of sinc_table_size
-    {
-        return sinc_table_size / 2 + 2;
-    }
-
-    public void interpolate(float[] in, float[] in_offset, float in_end,
-            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
-            int out_end) {
-        float pitch = startpitch[0];
-        float ix = in_offset[0];
-        int ox = out_offset[0];
-        float ix_end = in_end;
-        int ox_end = out_end;
-
-        if (pitchstep == 0) {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float[] sinc_table
-                        = this.sinc_table[(int) ((ix - iix) * sinc_table_fsize)];
-                int xx = iix - sinc_table_center;
-                float y = 0;
-                for (int i = 0; i < sinc_table_size; i++, xx++)
-                    y += in[xx] * sinc_table[i];
-                out[ox++] = y;
-                ix += pitch;
-            }
-        } else {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float[] sinc_table
-                        = this.sinc_table[(int) ((ix - iix) * sinc_table_fsize)];
-                int xx = iix - sinc_table_center;
-                float y = 0;
-                for (int i = 0; i < sinc_table_size; i++, xx++)
-                    y += in[xx] * sinc_table[i];
-                out[ox++] = y;
-
-                ix += pitch;
-                pitch += pitchstep;
-            }
-        }
-        in_offset[0] = ix;
-        out_offset[0] = ox;
-        startpitch[0] = pitch;
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Lanczos interpolation resampler.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLanczosResampler extends SoftAbstractResampler {
+
+    double[] din;
+    float[][] sinc_table;
+    int sinc_table_fsize = 2000;
+    int sinc_table_size = 5;
+    int sinc_table_center = sinc_table_size / 2;
+
+    public SoftLanczosResampler() {
+        super();
+        sinc_table = new float[sinc_table_fsize][];
+        for (int i = 0; i < sinc_table_fsize; i++) {
+            sinc_table[i] = sincTable(sinc_table_size, -i
+                            / ((float) sinc_table_fsize));
+        }
+    }
+
+    // Normalized sinc function
+    public static double sinc(double x) {
+        return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
+    }
+
+    // Generate sinc table
+    public static float[] sincTable(int size, float offset) {
+        int center = size / 2;
+        float[] w = new float[size];
+        for (int k = 0; k < size; k++) {
+            float x = (-center + k + offset);
+            if (x < -2 || x > 2)
+                w[k] = 0;
+            else if (x == 0)
+                w[k] = 1;
+            else {
+                w[k] = (float)(2.0 * Math.sin(Math.PI * x)
+                                * Math.sin(Math.PI * x / 2.0)
+                                / ((Math.PI * x) * (Math.PI * x)));
+            }
+        }
+        return w;
+    }
+
+    public int getPadding() // must be at least half of sinc_table_size
+    {
+        return sinc_table_size / 2 + 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+
+        if (pitchstep == 0) {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float[] sinc_table
+                        = this.sinc_table[(int) ((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float[] sinc_table
+                        = this.sinc_table[(int) ((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLimiter.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,191 +1,191 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A simple look-ahead volume limiter with very fast attack and fast release.
- * This filter is used for preventing clipping.
- *
- * @author Karl Helgason
- */
-public class SoftLimiter implements SoftAudioProcessor {
-
-    float lastmax = 0;
-    float gain = 1;
-    float[] temp_bufferL;
-    float[] temp_bufferR;
-    boolean mix = false;
-    SoftAudioBuffer bufferL;
-    SoftAudioBuffer bufferR;
-    SoftAudioBuffer bufferLout;
-    SoftAudioBuffer bufferRout;
-    SoftSynthesizer synth;
-
-    public void init(SoftSynthesizer synth) {
-        this.synth = synth;
-    }
-
-    public void setInput(int pin, SoftAudioBuffer input) {
-        if (pin == 0)
-            bufferL = input;
-        if (pin == 1)
-            bufferR = input;
-    }
-
-    public void setOutput(int pin, SoftAudioBuffer output) {
-        if (pin == 0)
-            bufferLout = output;
-        if (pin == 1)
-            bufferRout = output;
-    }
-
-    public void setMixMode(boolean mix) {
-        this.mix = mix;
-    }
-
-    public void globalParameterControlChange(int[] slothpath, long param,
-            long value) {
-    }
-
-    double silentcounter = 0;
-
-    public void processAudio() {
-        if (this.bufferL.isSilent()
-                && (this.bufferR == null || this.bufferR.isSilent())) {
-            silentcounter += 1 / synth.getControlRate();
-
-            if (silentcounter > 60) {
-                if (!mix) {
-                    bufferLout.clear();
-                    bufferRout.clear();
-                }
-                return;
-            }
-        } else
-            silentcounter = 0;
-
-        float[] bufferL = this.bufferL.array();
-        float[] bufferR = this.bufferR == null ? null : this.bufferR.array();
-        float[] bufferLout = this.bufferLout.array();
-        float[] bufferRout = this.bufferRout == null
-                                ? null : this.bufferRout.array();
-
-        if (temp_bufferL == null || temp_bufferL.length < bufferL.length)
-            temp_bufferL = new float[bufferL.length];
-        if (bufferR != null)
-            if (temp_bufferR == null || temp_bufferR.length < bufferR.length)
-                temp_bufferR = new float[bufferR.length];
-
-        float max = 0;
-        int len = bufferL.length;
-
-        if (bufferR == null) {
-            for (int i = 0; i < len; i++) {
-                if (bufferL[i] > max)
-                    max = bufferL[i];
-                if (-bufferL[i] > max)
-                    max = -bufferL[i];
-            }
-        } else {
-            for (int i = 0; i < len; i++) {
-                if (bufferL[i] > max)
-                    max = bufferL[i];
-                if (bufferR[i] > max)
-                    max = bufferR[i];
-                if (-bufferL[i] > max)
-                    max = -bufferL[i];
-                if (-bufferR[i] > max)
-                    max = -bufferR[i];
-            }
-        }
-
-        float lmax = lastmax;
-        lastmax = max;
-        if (lmax > max)
-            max = lmax;
-
-        float newgain = 1;
-        if (max > 0.99f)
-            newgain = 0.99f / max;
-        else
-            newgain = 1;
-
-        if (newgain > gain)
-            newgain = (newgain + gain * 9) / 10f;
-
-        float gaindelta = (newgain - gain) / len;
-        if (mix) {
-            if (bufferR == null) {
-                for (int i = 0; i < len; i++) {
-                    gain += gaindelta;
-                    float bL = bufferL[i];
-                    float tL = temp_bufferL[i];
-                    temp_bufferL[i] = bL;
-                    bufferLout[i] += tL * gain;
-                }
-            } else {
-                for (int i = 0; i < len; i++) {
-                    gain += gaindelta;
-                    float bL = bufferL[i];
-                    float bR = bufferR[i];
-                    float tL = temp_bufferL[i];
-                    float tR = temp_bufferR[i];
-                    temp_bufferL[i] = bL;
-                    temp_bufferR[i] = bR;
-                    bufferLout[i] += tL * gain;
-                    bufferRout[i] += tR * gain;
-                }
-            }
-
-        } else {
-            if (bufferR == null) {
-                for (int i = 0; i < len; i++) {
-                    gain += gaindelta;
-                    float bL = bufferL[i];
-                    float tL = temp_bufferL[i];
-                    temp_bufferL[i] = bL;
-                    bufferLout[i] = tL * gain;
-                }
-            } else {
-                for (int i = 0; i < len; i++) {
-                    gain += gaindelta;
-                    float bL = bufferL[i];
-                    float bR = bufferR[i];
-                    float tL = temp_bufferL[i];
-                    float tR = temp_bufferR[i];
-                    temp_bufferL[i] = bL;
-                    temp_bufferR[i] = bR;
-                    bufferLout[i] = tL * gain;
-                    bufferRout[i] = tR * gain;
-                }
-            }
-
-        }
-        gain = newgain;
-    }
-
-    public void processControlLogic() {
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A simple look-ahead volume limiter with very fast attack and fast release.
+ * This filter is used for preventing clipping.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLimiter implements SoftAudioProcessor {
+
+    float lastmax = 0;
+    float gain = 1;
+    float[] temp_bufferL;
+    float[] temp_bufferR;
+    boolean mix = false;
+    SoftAudioBuffer bufferL;
+    SoftAudioBuffer bufferR;
+    SoftAudioBuffer bufferLout;
+    SoftAudioBuffer bufferRout;
+    SoftSynthesizer synth;
+
+    public void init(SoftSynthesizer synth) {
+        this.synth = synth;
+    }
+
+    public void setInput(int pin, SoftAudioBuffer input) {
+        if (pin == 0)
+            bufferL = input;
+        if (pin == 1)
+            bufferR = input;
+    }
+
+    public void setOutput(int pin, SoftAudioBuffer output) {
+        if (pin == 0)
+            bufferLout = output;
+        if (pin == 1)
+            bufferRout = output;
+    }
+
+    public void setMixMode(boolean mix) {
+        this.mix = mix;
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value) {
+    }
+
+    double silentcounter = 0;
+
+    public void processAudio() {
+        if (this.bufferL.isSilent()
+                && (this.bufferR == null || this.bufferR.isSilent())) {
+            silentcounter += 1 / synth.getControlRate();
+
+            if (silentcounter > 60) {
+                if (!mix) {
+                    bufferLout.clear();
+                    bufferRout.clear();
+                }
+                return;
+            }
+        } else
+            silentcounter = 0;
+
+        float[] bufferL = this.bufferL.array();
+        float[] bufferR = this.bufferR == null ? null : this.bufferR.array();
+        float[] bufferLout = this.bufferLout.array();
+        float[] bufferRout = this.bufferRout == null
+                                ? null : this.bufferRout.array();
+
+        if (temp_bufferL == null || temp_bufferL.length < bufferL.length)
+            temp_bufferL = new float[bufferL.length];
+        if (bufferR != null)
+            if (temp_bufferR == null || temp_bufferR.length < bufferR.length)
+                temp_bufferR = new float[bufferR.length];
+
+        float max = 0;
+        int len = bufferL.length;
+
+        if (bufferR == null) {
+            for (int i = 0; i < len; i++) {
+                if (bufferL[i] > max)
+                    max = bufferL[i];
+                if (-bufferL[i] > max)
+                    max = -bufferL[i];
+            }
+        } else {
+            for (int i = 0; i < len; i++) {
+                if (bufferL[i] > max)
+                    max = bufferL[i];
+                if (bufferR[i] > max)
+                    max = bufferR[i];
+                if (-bufferL[i] > max)
+                    max = -bufferL[i];
+                if (-bufferR[i] > max)
+                    max = -bufferR[i];
+            }
+        }
+
+        float lmax = lastmax;
+        lastmax = max;
+        if (lmax > max)
+            max = lmax;
+
+        float newgain = 1;
+        if (max > 0.99f)
+            newgain = 0.99f / max;
+        else
+            newgain = 1;
+
+        if (newgain > gain)
+            newgain = (newgain + gain * 9) / 10f;
+
+        float gaindelta = (newgain - gain) / len;
+        if (mix) {
+            if (bufferR == null) {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float tL = temp_bufferL[i];
+                    temp_bufferL[i] = bL;
+                    bufferLout[i] += tL * gain;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float bR = bufferR[i];
+                    float tL = temp_bufferL[i];
+                    float tR = temp_bufferR[i];
+                    temp_bufferL[i] = bL;
+                    temp_bufferR[i] = bR;
+                    bufferLout[i] += tL * gain;
+                    bufferRout[i] += tR * gain;
+                }
+            }
+
+        } else {
+            if (bufferR == null) {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float tL = temp_bufferL[i];
+                    temp_bufferL[i] = bL;
+                    bufferLout[i] = tL * gain;
+                }
+            } else {
+                for (int i = 0; i < len; i++) {
+                    gain += gaindelta;
+                    float bL = bufferL[i];
+                    float bR = bufferR[i];
+                    float tL = temp_bufferL[i];
+                    float tR = temp_bufferR[i];
+                    temp_bufferL[i] = bL;
+                    temp_bufferR[i] = bR;
+                    bufferLout[i] = tL * gain;
+                    bufferRout[i] = tR * gain;
+                }
+            }
+
+        }
+        gain = newgain;
+    }
+
+    public void processControlLogic() {
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,70 +1,70 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A resampler that uses first-order (linear) interpolation.
- *
- * @author Karl Helgason
- */
-public class SoftLinearResampler extends SoftAbstractResampler {
-
-    public int getPadding() {
-        return 2;
-    }
-
-    public void interpolate(float[] in, float[] in_offset, float in_end,
-            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
-            int out_end) {
-
-        float pitch = startpitch[0];
-        float ix = in_offset[0];
-        int ox = out_offset[0];
-        float ix_end = in_end;
-        int ox_end = out_end;
-        if (pitchstep == 0f) {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float fix = ix - iix;
-                float i = in[iix];
-                out[ox++] = i + (in[iix + 1] - i) * fix;
-                ix += pitch;
-            }
-        } else {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float fix = ix - iix;
-                float i = in[iix];
-                out[ox++] = i + (in[iix + 1] - i) * fix;
-                ix += pitch;
-                pitch += pitchstep;
-            }
-        }
-        in_offset[0] = ix;
-        out_offset[0] = ox;
-        startpitch[0] = pitch;
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses first-order (linear) interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLinearResampler extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        if (pitchstep == 0f) {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler2.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLinearResampler2.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,108 +1,108 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A resampler that uses first-order (linear) interpolation.
- *
- * This one doesn't perform float to int casting inside the processing loop.
- *
- * @author Karl Helgason
- */
-public class SoftLinearResampler2 extends SoftAbstractResampler {
-
-    public int getPadding() {
-        return 2;
-    }
-
-    public void interpolate(float[] in, float[] in_offset, float in_end,
-            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
-            int out_end) {
-
-        float pitch = startpitch[0];
-        float ix = in_offset[0];
-        int ox = out_offset[0];
-        float ix_end = in_end;
-        int ox_end = out_end;
-
-        // Check if we have do anything
-        if (!(ix < ix_end && ox < ox_end))
-            return;
-
-        // 15 bit shift was choosed because
-        // it resulted in no drift between p_ix and ix.
-        int p_ix = (int) (ix * (1 << 15));
-        int p_ix_end = (int) (ix_end * (1 << 15));
-        int p_pitch = (int) (pitch * (1 << 15));
-        // Pitch needs to recalculated
-        // to ensure no drift between p_ix and ix.
-        pitch = p_pitch * (1f / (1 << 15));
-
-        if (pitchstep == 0f) {
-
-            // To reduce
-            //    while (p_ix < p_ix_end && ox < ox_end)
-            // into
-            //    while  (ox < ox_end)
-            // We need to calculate new ox_end value.
-            int p_ix_len = p_ix_end - p_ix;
-            int p_mod = p_ix_len % p_pitch;
-            if (p_mod != 0)
-                p_ix_len += p_pitch - p_mod;
-            int ox_end2 = ox + p_ix_len / p_pitch;
-            if (ox_end2 < ox_end)
-                ox_end = ox_end2;
-
-            while (ox < ox_end) {
-                int iix = p_ix >> 15;
-                float fix = ix - iix;
-                float i = in[iix];
-                out[ox++] = i + (in[iix + 1] - i) * fix;
-                p_ix += p_pitch;
-                ix += pitch;
-            }
-
-        } else {
-
-            int p_pitchstep = (int) (pitchstep * (1 << 15));
-            pitchstep = p_pitchstep * (1f / (1 << 15));
-
-            while (p_ix < p_ix_end && ox < ox_end) {
-                int iix = p_ix >> 15;
-                float fix = ix - iix;
-                float i = in[iix];
-                out[ox++] = i + (in[iix + 1] - i) * fix;
-                ix += pitch;
-                p_ix += p_pitch;
-                pitch += pitchstep;
-                p_pitch += p_pitchstep;
-            }
-        }
-        in_offset[0] = ix;
-        out_offset[0] = ox;
-        startpitch[0] = pitch;
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses first-order (linear) interpolation.
+ *
+ * This one doesn't perform float to int casting inside the processing loop.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLinearResampler2 extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+
+        // Check if we have do anything
+        if (!(ix < ix_end && ox < ox_end))
+            return;
+
+        // 15 bit shift was choosed because
+        // it resulted in no drift between p_ix and ix.
+        int p_ix = (int) (ix * (1 << 15));
+        int p_ix_end = (int) (ix_end * (1 << 15));
+        int p_pitch = (int) (pitch * (1 << 15));
+        // Pitch needs to recalculated
+        // to ensure no drift between p_ix and ix.
+        pitch = p_pitch * (1f / (1 << 15));
+
+        if (pitchstep == 0f) {
+
+            // To reduce
+            //    while (p_ix < p_ix_end && ox < ox_end)
+            // into
+            //    while  (ox < ox_end)
+            // We need to calculate new ox_end value.
+            int p_ix_len = p_ix_end - p_ix;
+            int p_mod = p_ix_len % p_pitch;
+            if (p_mod != 0)
+                p_ix_len += p_pitch - p_mod;
+            int ox_end2 = ox + p_ix_len / p_pitch;
+            if (ox_end2 < ox_end)
+                ox_end = ox_end2;
+
+            while (ox < ox_end) {
+                int iix = p_ix >> 15;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                p_ix += p_pitch;
+                ix += pitch;
+            }
+
+        } else {
+
+            int p_pitchstep = (int) (pitchstep * (1 << 15));
+            pitchstep = p_pitchstep * (1f / (1 << 15));
+
+            while (p_ix < p_ix_end && ox < ox_end) {
+                int iix = p_ix >> 15;
+                float fix = ix - iix;
+                float i = in[iix];
+                out[ox++] = i + (in[iix + 1] - i) * fix;
+                ix += pitch;
+                p_ix += p_pitch;
+                pitch += pitchstep;
+                p_pitch += p_pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftLowFrequencyOscillator.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftLowFrequencyOscillator.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,122 +1,122 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * LFO control signal generator.
- *
- * @author Karl Helgason
- */
-public class SoftLowFrequencyOscillator implements SoftProcess {
-
-    private int max_count = 10;
-    private int used_count = 0;
-    private double[][] out = new double[max_count][1];
-    private double[][] delay = new double[max_count][1];
-    private double[][] delay2 = new double[max_count][1];
-    private double[][] freq = new double[max_count][1];
-    private int[] delay_counter = new int[max_count];
-    private double[] sin_phase = new double[max_count];
-    private double[] sin_stepfreq = new double[max_count];
-    private double[] sin_step = new double[max_count];
-    private double control_time = 0;
-    private double sin_factor = 0;
-    private static double PI2 = 2.0 * Math.PI;
-
-    public void reset() {
-        for (int i = 0; i < used_count; i++) {
-            out[i][0] = 0;
-            delay[i][0] = 0;
-            delay2[i][0] = 0;
-            freq[i][0] = 0;
-            delay_counter[i] = 0;
-            sin_phase[i] = 0;
-            sin_stepfreq[i] = 0;
-            sin_step[i] = 0;
-        }
-        used_count = 0;
-    }
-
-    public void init(SoftSynthesizer synth) {
-        control_time = 1.0 / synth.getControlRate();
-        sin_factor = control_time * 2 * Math.PI;
-        for (int i = 0; i < used_count; i++) {
-            delay_counter[i] = (int)(Math.pow(2,
-                    this.delay[i][0] / 1200.0) / control_time);
-            delay_counter[i] += (int)(delay2[i][0] / (control_time * 1000));
-        }
-        processControlLogic();
-    }
-
-    public void processControlLogic() {
-        for (int i = 0; i < used_count; i++) {
-            if (delay_counter[i] > 0) {
-                delay_counter[i]--;
-                out[i][0] = 0.5;
-            } else {
-                double f = freq[i][0];
-
-                if (sin_stepfreq[i] != f) {
-                    sin_stepfreq[i] = f;
-                    double fr = 440.0 * Math.exp(
-                            (f - 6900.0) * (Math.log(2) / 1200.0));
-                    sin_step[i] = fr * sin_factor;
-                }
-                /*
-                double fr = 440.0 * Math.pow(2.0,
-                (freq[i][0] - 6900.0) / 1200.0);
-                sin_phase[i] += fr * sin_factor;
-                 */
-                /*
-                sin_phase[i] += sin_step[i];
-                while (sin_phase[i] > PI2)
-                sin_phase[i] -= PI2;
-                out[i][0] = 0.5 + Math.sin(sin_phase[i]) * 0.5;
-                 */
-                double p = sin_phase[i];
-                p += sin_step[i];
-                while (p > PI2)
-                    p -= PI2;
-                out[i][0] = 0.5 + Math.sin(p) * 0.5;
-                sin_phase[i] = p;
-
-            }
-        }
-    }
-
-    public double[] get(int instance, String name) {
-        if (instance >= used_count)
-            used_count = instance + 1;
-        if (name == null)
-            return out[instance];
-        if (name.equals("delay"))
-            return delay[instance];
-        if (name.equals("delay2"))
-            return delay2[instance];
-        if (name.equals("freq"))
-            return freq[instance];
-        return null;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * LFO control signal generator.
+ *
+ * @author Karl Helgason
+ */
+public class SoftLowFrequencyOscillator implements SoftProcess {
+
+    private int max_count = 10;
+    private int used_count = 0;
+    private double[][] out = new double[max_count][1];
+    private double[][] delay = new double[max_count][1];
+    private double[][] delay2 = new double[max_count][1];
+    private double[][] freq = new double[max_count][1];
+    private int[] delay_counter = new int[max_count];
+    private double[] sin_phase = new double[max_count];
+    private double[] sin_stepfreq = new double[max_count];
+    private double[] sin_step = new double[max_count];
+    private double control_time = 0;
+    private double sin_factor = 0;
+    private static double PI2 = 2.0 * Math.PI;
+
+    public void reset() {
+        for (int i = 0; i < used_count; i++) {
+            out[i][0] = 0;
+            delay[i][0] = 0;
+            delay2[i][0] = 0;
+            freq[i][0] = 0;
+            delay_counter[i] = 0;
+            sin_phase[i] = 0;
+            sin_stepfreq[i] = 0;
+            sin_step[i] = 0;
+        }
+        used_count = 0;
+    }
+
+    public void init(SoftSynthesizer synth) {
+        control_time = 1.0 / synth.getControlRate();
+        sin_factor = control_time * 2 * Math.PI;
+        for (int i = 0; i < used_count; i++) {
+            delay_counter[i] = (int)(Math.pow(2,
+                    this.delay[i][0] / 1200.0) / control_time);
+            delay_counter[i] += (int)(delay2[i][0] / (control_time * 1000));
+        }
+        processControlLogic();
+    }
+
+    public void processControlLogic() {
+        for (int i = 0; i < used_count; i++) {
+            if (delay_counter[i] > 0) {
+                delay_counter[i]--;
+                out[i][0] = 0.5;
+            } else {
+                double f = freq[i][0];
+
+                if (sin_stepfreq[i] != f) {
+                    sin_stepfreq[i] = f;
+                    double fr = 440.0 * Math.exp(
+                            (f - 6900.0) * (Math.log(2) / 1200.0));
+                    sin_step[i] = fr * sin_factor;
+                }
+                /*
+                double fr = 440.0 * Math.pow(2.0,
+                (freq[i][0] - 6900.0) / 1200.0);
+                sin_phase[i] += fr * sin_factor;
+                 */
+                /*
+                sin_phase[i] += sin_step[i];
+                while (sin_phase[i] > PI2)
+                sin_phase[i] -= PI2;
+                out[i][0] = 0.5 + Math.sin(sin_phase[i]) * 0.5;
+                 */
+                double p = sin_phase[i];
+                p += sin_step[i];
+                while (p > PI2)
+                    p -= PI2;
+                out[i][0] = 0.5 + Math.sin(p) * 0.5;
+                sin_phase[i] = p;
+
+            }
+        }
+    }
+
+    public double[] get(int instance, String name) {
+        if (instance >= used_count)
+            used_count = instance + 1;
+        if (name == null)
+            return out[instance];
+        if (name.equals("delay"))
+            return delay[instance];
+        if (name.equals("delay2"))
+            return delay2[instance];
+        if (name.equals("freq"))
+            return freq[instance];
+        return null;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftMainMixer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,943 +1,943 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.Map.Entry;
-
-import javax.sound.midi.MidiMessage;
-import javax.sound.midi.Patch;
-import javax.sound.midi.ShortMessage;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-
-/**
- * Software synthesizer main audio mixer.
- *
- * @author Karl Helgason
- */
-public class SoftMainMixer {
-
-    public final static int CHANNEL_LEFT = 0;
-    public final static int CHANNEL_RIGHT = 1;
-    public final static int CHANNEL_EFFECT1 = 2;
-    public final static int CHANNEL_EFFECT2 = 3;
-    public final static int CHANNEL_EFFECT3 = 4;
-    public final static int CHANNEL_EFFECT4 = 5;
-    public final static int CHANNEL_LEFT_DRY = 10;
-    public final static int CHANNEL_RIGHT_DRY = 11;
-    public final static int CHANNEL_SCRATCH1 = 12;
-    public final static int CHANNEL_SCRATCH2 = 13;
-    public final static int CHANNEL_CHANNELMIXER_LEFT = 14;
-    public final static int CHANNEL_CHANNELMIXER_RIGHT = 15;
-    protected boolean active_sensing_on = false;
-    protected long msec_last_activity = -1;
-    protected long msec_pos = 0;
-    protected boolean readfully = true;
-    private Object control_mutex;
-    private SoftSynthesizer synth;
-    private int nrofchannels = 2;
-    private SoftVoice[] voicestatus = null;
-    private SoftAudioBuffer[] buffers;
-    private SoftAudioProcessor reverb;
-    private SoftAudioProcessor chorus;
-    private SoftAudioProcessor agc;
-    private long msec_buffer_len = 0;
-    protected TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>();
-    double finetuning = 0;
-    double coarsetuning = 0;
-    double last_volume_left = 1.0;
-    double last_volume_right = 1.0;
-    private double[] co_master_balance = new double[1];
-    private double[] co_master_volume = new double[1];
-    private double[] co_master_coarse_tuning = new double[1];
-    private double[] co_master_fine_tuning = new double[1];
-    private AudioInputStream ais;
-    private Set<ModelChannelMixer> registeredMixers = null;
-    private Set<ModelChannelMixer> stoppedMixers = null;
-    private ModelChannelMixer[] cur_registeredMixers = null;
-    protected SoftControl co_master = new SoftControl() {
-
-        double[] balance = co_master_balance;
-        double[] volume = co_master_volume;
-        double[] coarse_tuning = co_master_coarse_tuning;
-        double[] fine_tuning = co_master_fine_tuning;
-
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            if (name.equals("balance"))
-                return balance;
-            if (name.equals("volume"))
-                return volume;
-            if (name.equals("coarse_tuning"))
-                return coarse_tuning;
-            if (name.equals("fine_tuning"))
-                return fine_tuning;
-            return null;
-        }
-    };
-
-    private void processSystemExclusiveMessage(byte[] data) {
-        synchronized (synth.control_mutex) {
-            msec_last_activity = msec_pos;
-
-            // Universal Non-Real-Time SysEx
-            if ((data[1] & 0xFF) == 0x7E) {
-                int deviceID = data[2] & 0xFF;
-                if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
-                    int subid1 = data[3] & 0xFF;
-                    int subid2;
-                    switch (subid1) {
-                    case 0x08:  // MIDI Tuning Standard
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x01:  // BULK TUNING DUMP
-                        {
-                            // http://www.midi.org/about-midi/tuning.shtml
-                            SoftTuning tuning = synth.getTuning(new Patch(0,
-                                    data[5] & 0xFF));
-                            tuning.load(data);
-                            break;
-                        }
-                        case 0x04:  // KEY-BASED TUNING DUMP
-                        case 0x05:  // SCALE/OCTAVE TUNING DUMP, 1 byte format
-                        case 0x06:  // SCALE/OCTAVE TUNING DUMP, 2 byte format
-                        case 0x07:  // SINGLE NOTE TUNING CHANGE (NON REAL-TIME)
-                                    // (BANK)
-                        {
-                            // http://www.midi.org/about-midi/tuning_extens.shtml
-                            SoftTuning tuning = synth.getTuning(new Patch(
-                                    data[5] & 0xFF, data[6] & 0xFF));
-                            tuning.load(data);
-                            break;
-                        }
-                        case 0x08:  // scale/octave tuning 1-byte form (Non
-                                    // Real-Time)
-                        case 0x09:  // scale/octave tuning 2-byte form (Non
-                                    // Real-Time)
-                        {
-                            // http://www.midi.org/about-midi/tuning-scale.shtml
-                            SoftTuning tuning = new SoftTuning(data);
-                            int channelmask = (data[5] & 0xFF) * 16384
-                                    + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
-                            SoftChannel[] channels = synth.channels;
-                            for (int i = 0; i < channels.length; i++)
-                                if ((channelmask & (1 << i)) != 0)
-                                    channels[i].tuning = tuning;
-                            break;
-                        }
-                        default:
-                            break;
-                        }
-                        break;
-                    case 0x09:  // General Midi Message
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x01:  // General Midi 1 On
-                            synth.setGeneralMidiMode(1);
-                            reset();
-                            break;
-                        case 0x02:  // General Midi Off
-                            synth.setGeneralMidiMode(0);
-                            reset();
-                            break;
-                        case 0x03:  // General MidI Level 2 On
-                            synth.setGeneralMidiMode(2);
-                            reset();
-                            break;
-                        default:
-                            break;
-                        }
-                        break;
-                    case 0x0A: // DLS Message
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x01:  // DLS On
-                            if (synth.getGeneralMidiMode() == 0)
-                                synth.setGeneralMidiMode(1);
-                            synth.voice_allocation_mode = 1;
-                            reset();
-                            break;
-                        case 0x02:  // DLS Off
-                            synth.setGeneralMidiMode(0);
-                            synth.voice_allocation_mode = 0;
-                            reset();
-                            break;
-                        case 0x03:  // DLS Static Voice Allocation Off
-                            synth.voice_allocation_mode = 0;
-                            break;
-                        case 0x04:  // DLS Static Voice Allocation On
-                            synth.voice_allocation_mode = 1;
-                            break;
-                        default:
-                            break;
-                        }
-                        break;
-
-                    default:
-                        break;
-                    }
-                }
-            }
-
-            // Universal Real-Time SysEx
-            if ((data[1] & 0xFF) == 0x7F) {
-                int deviceID = data[2] & 0xFF;
-                if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
-                    int subid1 = data[3] & 0xFF;
-                    int subid2;
-                    switch (subid1) {
-                    case 0x04: // Device Control
-
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x01: // Master Volume
-                        case 0x02: // Master Balane
-                        case 0x03: // Master fine tuning
-                        case 0x04: // Master coarse tuning
-                            int val = (data[5] & 0x7F)
-                                    + ((data[6] & 0x7F) * 128);
-                            if (subid2 == 0x01)
-                                setVolume(val);
-                            else if (subid2 == 0x02)
-                                setBalance(val);
-                            else if (subid2 == 0x03)
-                                setFineTuning(val);
-                            else if (subid2 == 0x04)
-                                setCoarseTuning(val);
-                            break;
-                        case 0x05: // Global Parameter Control
-                            int ix = 5;
-                            int slotPathLen = (data[ix++] & 0xFF);
-                            int paramWidth = (data[ix++] & 0xFF);
-                            int valueWidth = (data[ix++] & 0xFF);
-                            int[] slotPath = new int[slotPathLen];
-                            for (int i = 0; i < slotPathLen; i++) {
-                                int msb = (data[ix++] & 0xFF);
-                                int lsb = (data[ix++] & 0xFF);
-                                slotPath[i] = msb * 128 + lsb;
-                            }
-                            int paramCount = (data.length - 1 - ix)
-                                    / (paramWidth + valueWidth);
-                            long[] params = new long[paramCount];
-                            long[] values = new long[paramCount];
-                            for (int i = 0; i < paramCount; i++) {
-                                values[i] = 0;
-                                for (int j = 0; j < paramWidth; j++)
-                                    params[i] = params[i] * 128
-                                            + (data[ix++] & 0xFF);
-                                for (int j = 0; j < valueWidth; j++)
-                                    values[i] = values[i] * 128
-                                            + (data[ix++] & 0xFF);
-
-                            }
-                            globalParameterControlChange(slotPath, params, values);
-                            break;
-                        default:
-                            break;
-                        }
-                        break;
-
-                    case 0x08:  // MIDI Tuning Standard
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x02:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
-                        {
-                            // http://www.midi.org/about-midi/tuning.shtml
-                            SoftTuning tuning = synth.getTuning(new Patch(0,
-                                    data[5] & 0xFF));
-                            tuning.load(data);
-                            SoftVoice[] voices = synth.getVoices();
-                            for (int i = 0; i < voices.length; i++)
-                                if (voices[i].active)
-                                    if (voices[i].tuning == tuning)
-                                        voices[i].updateTuning(tuning);
-                            break;
-                        }
-                        case 0x07:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
-                                    // (BANK)
-                        {
-                            // http://www.midi.org/about-midi/tuning_extens.shtml
-                            SoftTuning tuning = synth.getTuning(new Patch(
-                                    data[5] & 0xFF, data[6] & 0xFF));
-                            tuning.load(data);
-                            SoftVoice[] voices = synth.getVoices();
-                            for (int i = 0; i < voices.length; i++)
-                                if (voices[i].active)
-                                    if (voices[i].tuning == tuning)
-                                        voices[i].updateTuning(tuning);
-                            break;
-                        }
-                        case 0x08:  // scale/octave tuning 1-byte form
-                                    //(Real-Time)
-                        case 0x09:  // scale/octave tuning 2-byte form
-                                    // (Real-Time)
-                        {
-                            // http://www.midi.org/about-midi/tuning-scale.shtml
-                            SoftTuning tuning = new SoftTuning(data);
-                            int channelmask = (data[5] & 0xFF) * 16384
-                                    + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
-                            SoftChannel[] channels = synth.channels;
-                            for (int i = 0; i < channels.length; i++)
-                                if ((channelmask & (1 << i)) != 0)
-                                    channels[i].tuning = tuning;
-                            SoftVoice[] voices = synth.getVoices();
-                            for (int i = 0; i < voices.length; i++)
-                                if (voices[i].active)
-                                    if ((channelmask & (1 << (voices[i].channel))) != 0)
-                                        voices[i].updateTuning(tuning);
-                            break;
-                        }
-                        default:
-                            break;
-                        }
-                        break;
-                    case 0x09:  // Control Destination Settings
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x01: // Channel Pressure
-                        {
-                            int[] destinations = new int[(data.length - 7) / 2];
-                            int[] ranges = new int[(data.length - 7) / 2];
-                            int ix = 0;
-                            for (int j = 6; j < data.length - 1; j += 2) {
-                                destinations[ix] = data[j] & 0xFF;
-                                ranges[ix] = data[j + 1] & 0xFF;
-                                ix++;
-                            }
-                            int channel = data[5] & 0xFF;
-                            SoftChannel softchannel = synth.channels[channel];
-                            softchannel.mapChannelPressureToDestination(
-                                    destinations, ranges);
-                            break;
-                        }
-                        case 0x02: // Poly Pressure
-                        {
-                            int[] destinations = new int[(data.length - 7) / 2];
-                            int[] ranges = new int[(data.length - 7) / 2];
-                            int ix = 0;
-                            for (int j = 6; j < data.length - 1; j += 2) {
-                                destinations[ix] = data[j] & 0xFF;
-                                ranges[ix] = data[j + 1] & 0xFF;
-                                ix++;
-                            }
-                            int channel = data[5] & 0xFF;
-                            SoftChannel softchannel = synth.channels[channel];
-                            softchannel.mapPolyPressureToDestination(
-                                    destinations, ranges);
-                            break;
-                        }
-                        case 0x03: // Control Change
-                        {
-                            int[] destinations = new int[(data.length - 7) / 2];
-                            int[] ranges = new int[(data.length - 7) / 2];
-                            int ix = 0;
-                            for (int j = 7; j < data.length - 1; j += 2) {
-                                destinations[ix] = data[j] & 0xFF;
-                                ranges[ix] = data[j + 1] & 0xFF;
-                                ix++;
-                            }
-                            int channel = data[5] & 0xFF;
-                            SoftChannel softchannel = synth.channels[channel];
-                            int control = data[6] & 0xFF;
-                            softchannel.mapControlToDestination(control,
-                                    destinations, ranges);
-                            break;
-                        }
-                        default:
-                            break;
-                        }
-                        break;
-
-                    case 0x0A:  // Key Based Instrument Control
-                    {
-                        subid2 = data[4] & 0xFF;
-                        switch (subid2) {
-                        case 0x01: // Basic Message
-                            int channel = data[5] & 0xFF;
-                            int keynumber = data[6] & 0xFF;
-                            SoftChannel softchannel = synth.channels[channel];
-                            for (int j = 7; j < data.length - 1; j += 2) {
-                                int controlnumber = data[j] & 0xFF;
-                                int controlvalue = data[j + 1] & 0xFF;
-                                softchannel.controlChangePerNote(keynumber,
-                                        controlnumber, controlvalue);
-                            }
-                            break;
-                        default:
-                            break;
-                        }
-                        break;
-                    }
-                    default:
-                        break;
-                    }
-                }
-            }
-
-        }
-    }
-
-    private void processMessages(long timeStamp) {
-        Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator();
-        while (iter.hasNext()) {
-            Entry<Long, Object> entry = iter.next();
-            if (entry.getKey() > (timeStamp + 100))
-                return;
-            processMessage(entry.getValue());
-            iter.remove();
-        }
-    }
-
-    protected void processAudioBuffers() {
-        for (int i = 0; i < buffers.length; i++) {
-            buffers[i].clear();
-        }
-
-        double volume_left;
-        double volume_right;
-
-        ModelChannelMixer[] act_registeredMixers;
-
-        // perform control logic
-        synchronized (control_mutex) {
-
-            processMessages(msec_pos);
-
-            if (active_sensing_on) {
-                // Active Sensing
-                // if no message occurs for max 1000 ms
-                // then do AllSoundOff on all channels
-                if ((msec_pos - msec_last_activity) > 1000000) {
-                    active_sensing_on = false;
-                    for (SoftChannel c : synth.channels)
-                        c.allSoundOff();
-                }
-
-            }
-
-            for (int i = 0; i < voicestatus.length; i++)
-                if (voicestatus[i].active)
-                    voicestatus[i].processControlLogic();
-            msec_pos += msec_buffer_len;
-
-            double volume = co_master_volume[0];
-            volume_left = volume;
-            volume_right = volume;
-
-            double balance = co_master_balance[0];
-            if (balance > 0.5)
-                volume_left *= (1 - balance) * 2;
-            else
-                volume_right *= balance * 2;
-
-            chorus.processControlLogic();
-            reverb.processControlLogic();
-            agc.processControlLogic();
-
-            if (cur_registeredMixers == null) {
-                if (registeredMixers != null) {
-                    cur_registeredMixers =
-                            new ModelChannelMixer[registeredMixers.size()];
-                    registeredMixers.toArray(cur_registeredMixers);
-                }
-            }
-
-            act_registeredMixers = cur_registeredMixers;
-            if (act_registeredMixers != null)
-                if (act_registeredMixers.length == 0)
-                    act_registeredMixers = null;
-
-        }
-
-        if (act_registeredMixers != null) {
-
-            // Reroute default left,right output
-            // to channelmixer left,right input/output
-            SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT];
-            SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT];
-            buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
-            buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
-
-            int bufferlen = buffers[CHANNEL_LEFT].getSize();
-
-            float[][] cbuffer = new float[nrofchannels][];
-            cbuffer[0] = buffers[CHANNEL_LEFT].array();
-            if (nrofchannels != 1)
-                cbuffer[1] = buffers[CHANNEL_RIGHT].array();
-
-            float[][] obuffer = new float[nrofchannels][];
-            obuffer[0] = leftbak.array();
-            if (nrofchannels != 1)
-                obuffer[1] = rightbak.array();
-
-            for (ModelChannelMixer cmixer : act_registeredMixers) {
-                for (int i = 0; i < cbuffer.length; i++)
-                    Arrays.fill(cbuffer[i], 0);
-                boolean hasactivevoices = false;
-                for (int i = 0; i < voicestatus.length; i++)
-                    if (voicestatus[i].active)
-                        if (voicestatus[i].channelmixer == cmixer) {
-                            voicestatus[i].processAudioLogic(buffers);
-                            hasactivevoices = true;
-                        }
-                if (!cmixer.process(cbuffer, 0, bufferlen)) {
-                    synchronized (control_mutex) {
-                        registeredMixers.remove(cmixer);
-                        cur_registeredMixers = null;
-                    }
-                }
-
-                for (int i = 0; i < cbuffer.length; i++) {
-                    float[] cbuff = cbuffer[i];
-                    float[] obuff = obuffer[i];
-                    for (int j = 0; j < bufferlen; j++)
-                        obuff[j] += cbuff[j];
-                }
-
-                if (!hasactivevoices) {
-                    synchronized (control_mutex) {
-                        if (stoppedMixers != null) {
-                            if (stoppedMixers.contains(cmixer)) {
-                                stoppedMixers.remove(cmixer);
-                                cmixer.stop();
-                            }
-                        }
-                    }
-                }
-
-            }
-
-            buffers[CHANNEL_LEFT] = leftbak;
-            buffers[CHANNEL_RIGHT] = rightbak;
-
-        }
-
-        for (int i = 0; i < voicestatus.length; i++)
-            if (voicestatus[i].active)
-                if (voicestatus[i].channelmixer == null)
-                    voicestatus[i].processAudioLogic(buffers);
-
-        // Run effects
-        if (synth.chorus_on)
-            chorus.processAudio();
-
-        if (synth.reverb_on)
-            reverb.processAudio();
-
-        if (nrofchannels == 1)
-            volume_left = (volume_left + volume_right) / 2;
-
-        // Set Volume / Balance
-        if (last_volume_left != volume_left || last_volume_right != volume_right) {
-            float[] left = buffers[CHANNEL_LEFT].array();
-            float[] right = buffers[CHANNEL_RIGHT].array();
-            int bufferlen = buffers[CHANNEL_LEFT].getSize();
-
-            float amp;
-            float amp_delta;
-            amp = (float)(last_volume_left * last_volume_left);
-            amp_delta = (float)((volume_left * volume_left - amp) / bufferlen);
-            for (int i = 0; i < bufferlen; i++) {
-                amp += amp_delta;
-                left[i] *= amp;
-            }
-            if (nrofchannels != 1) {
-                amp = (float)(last_volume_right * last_volume_right);
-                amp_delta = (float)((volume_right*volume_right - amp) / bufferlen);
-                for (int i = 0; i < bufferlen; i++) {
-                    amp += amp_delta;
-                    right[i] *= volume_right;
-                }
-            }
-            last_volume_left = volume_left;
-            last_volume_right = volume_right;
-
-        } else {
-            if (volume_left != 1.0 || volume_right != 1.0) {
-                float[] left = buffers[CHANNEL_LEFT].array();
-                float[] right = buffers[CHANNEL_RIGHT].array();
-                int bufferlen = buffers[CHANNEL_LEFT].getSize();
-                float amp;
-                amp = (float) (volume_left * volume_left);
-                for (int i = 0; i < bufferlen; i++)
-                    left[i] *= amp;
-                if (nrofchannels != 1) {
-                    amp = (float)(volume_right * volume_right);
-                    for (int i = 0; i < bufferlen; i++)
-                        right[i] *= amp;
-                }
-
-            }
-        }
-
-        if (synth.agc_on)
-            agc.processAudio();
-
-    }
-
-    public void stopMixer(ModelChannelMixer mixer) {
-        if (stoppedMixers == null)
-            stoppedMixers = new HashSet<ModelChannelMixer>();
-        stoppedMixers.add(mixer);
-    }
-
-    public void registerMixer(ModelChannelMixer mixer) {
-        if (registeredMixers == null)
-            registeredMixers = new HashSet<ModelChannelMixer>();
-        registeredMixers.add(mixer);
-        cur_registeredMixers = null;
-    }
-
-    public SoftMainMixer(SoftSynthesizer synth) {
-        this.synth = synth;
-
-        msec_pos = 0;
-
-        co_master_balance[0] = 0.5;
-        co_master_volume[0] = 1;
-        co_master_coarse_tuning[0] = 0.5;
-        co_master_fine_tuning[0] = 0.5;
-
-        msec_buffer_len = (long) (1000000.0 / synth.getControlRate());
-
-        nrofchannels = synth.getFormat().getChannels();
-
-        int buffersize = (int) (synth.getFormat().getSampleRate()
-                                / synth.getControlRate());
-
-        control_mutex = synth.control_mutex;
-        buffers = new SoftAudioBuffer[16];
-        for (int i = 0; i < buffers.length; i++) {
-            buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat());
-        }
-        voicestatus = synth.getVoices();
-
-        reverb = new SoftReverb();
-        chorus = new SoftChorus();
-        agc = new SoftLimiter();
-
-        reverb.init(synth);
-        chorus.init(synth);
-        agc.init(synth);
-
-        reverb.setMixMode(true);
-        chorus.setMixMode(true);
-        agc.setMixMode(false);
-
-        chorus.setInput(0, buffers[CHANNEL_EFFECT2]);
-        chorus.setOutput(0, buffers[CHANNEL_LEFT]);
-        if (nrofchannels != 1)
-            chorus.setOutput(1, buffers[CHANNEL_RIGHT]);
-        chorus.setOutput(2, buffers[CHANNEL_EFFECT1]);
-
-        reverb.setInput(0, buffers[CHANNEL_EFFECT1]);
-        reverb.setOutput(0, buffers[CHANNEL_LEFT]);
-        if (nrofchannels != 1)
-            reverb.setOutput(1, buffers[CHANNEL_RIGHT]);
-
-        agc.setInput(0, buffers[CHANNEL_LEFT]);
-        if (nrofchannels != 1)
-            agc.setInput(1, buffers[CHANNEL_RIGHT]);
-        agc.setOutput(0, buffers[CHANNEL_LEFT]);
-        if (nrofchannels != 1)
-            agc.setOutput(1, buffers[CHANNEL_RIGHT]);
-
-        InputStream in = new InputStream() {
-
-            private SoftAudioBuffer[] buffers = SoftMainMixer.this.buffers;
-            private int nrofchannels
-                    = SoftMainMixer.this.synth.getFormat().getChannels();
-            private int buffersize = buffers[0].getSize();
-            private byte[] bbuffer = new byte[buffersize
-                    * (SoftMainMixer.this.synth.getFormat()
-                        .getSampleSizeInBits() / 8)
-                    * nrofchannels];
-            private int bbuffer_pos = 0;
-            private byte[] single = new byte[1];
-
-            public void fillBuffer() {
-                processAudioBuffers();
-                for (int i = 0; i < nrofchannels; i++)
-                    buffers[i].get(bbuffer, i);
-                bbuffer_pos = 0;
-            }
-
-            public int read(byte[] b, int off, int len) {
-                int bbuffer_len = bbuffer.length;
-                int offlen = off + len;
-                int orgoff = off;
-                byte[] bbuffer = this.bbuffer;
-                while (off < offlen) {
-                    if (available() == 0)
-                        fillBuffer();
-                    else {
-                        int bbuffer_pos = this.bbuffer_pos;
-                        while (off < offlen && bbuffer_pos < bbuffer_len)
-                            b[off++] = bbuffer[bbuffer_pos++];
-                        this.bbuffer_pos = bbuffer_pos;
-                        if (!readfully)
-                            return off - orgoff;
-                    }
-                }
-                return len;
-            }
-
-            public int read() throws IOException {
-                int ret = read(single);
-                if (ret == -1)
-                    return -1;
-                return single[0] & 0xFF;
-            }
-
-            public int available() {
-                return bbuffer.length - bbuffer_pos;
-            }
-
-            public void close() {
-                SoftMainMixer.this.synth.close();
-            }
-        };
-
-        ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED);
-
-    }
-
-    public AudioInputStream getInputStream() {
-        return ais;
-    }
-
-    public void reset() {
-
-        SoftChannel[] channels = synth.channels;
-        for (int i = 0; i < channels.length; i++) {
-            channels[i].allSoundOff();
-            channels[i].resetAllControllers(true);
-
-            if (synth.getGeneralMidiMode() == 2) {
-                if (i == 9)
-                    channels[i].programChange(0, 0x78 * 128);
-                else
-                    channels[i].programChange(0, 0x79 * 128);
-            } else
-                channels[i].programChange(0, 0);
-        }
-        setVolume(0x7F * 128 + 0x7F);
-        setBalance(0x40 * 128 + 0x00);
-        setCoarseTuning(0x40 * 128 + 0x00);
-        setFineTuning(0x40 * 128 + 0x00);
-        // Reset Reverb
-        globalParameterControlChange(
-                new int[]{0x01 * 128 + 0x01}, new long[]{0}, new long[]{4});
-        // Reset Chorus
-        globalParameterControlChange(
-                new int[]{0x01 * 128 + 0x02}, new long[]{0}, new long[]{2});
-    }
-
-    public void setVolume(int value) {
-        synchronized (control_mutex) {
-            co_master_volume[0] = value / 16384.0;
-        }
-    }
-
-    public void setBalance(int value) {
-        synchronized (control_mutex) {
-            co_master_balance[0] = value / 16384.0;
-        }
-    }
-
-    public void setFineTuning(int value) {
-        synchronized (control_mutex) {
-            co_master_fine_tuning[0] = value / 16384.0;
-        }
-    }
-
-    public void setCoarseTuning(int value) {
-        synchronized (control_mutex) {
-            co_master_coarse_tuning[0] = value / 16384.0;
-        }
-    }
-
-    public int getVolume() {
-        synchronized (control_mutex) {
-            return (int) (co_master_volume[0] * 16384.0);
-        }
-    }
-
-    public int getBalance() {
-        synchronized (control_mutex) {
-            return (int) (co_master_balance[0] * 16384.0);
-        }
-    }
-
-    public int getFineTuning() {
-        synchronized (control_mutex) {
-            return (int) (co_master_fine_tuning[0] * 16384.0);
-        }
-    }
-
-    public int getCoarseTuning() {
-        synchronized (control_mutex) {
-            return (int) (co_master_coarse_tuning[0] * 16384.0);
-        }
-    }
-
-    public void globalParameterControlChange(int[] slothpath, long[] params,
-            long[] paramsvalue) {
-        if (slothpath.length == 0)
-            return;
-
-        synchronized (control_mutex) {
-
-            // slothpath: 01xx are reserved only for GM2
-
-            if (slothpath[0] == 0x01 * 128 + 0x01) {
-                for (int i = 0; i < paramsvalue.length; i++) {
-                    reverb.globalParameterControlChange(slothpath, params[i],
-                            paramsvalue[i]);
-                }
-            }
-            if (slothpath[0] == 0x01 * 128 + 0x02) {
-                for (int i = 0; i < paramsvalue.length; i++) {
-                    chorus.globalParameterControlChange(slothpath, params[i],
-                            paramsvalue[i]);
-                }
-
-            }
-
-        }
-    }
-
-    public void processMessage(Object object) {
-        if (object instanceof byte[])
-            processMessage((byte[]) object);
-        if (object instanceof MidiMessage)
-            processMessage((MidiMessage)object);
-    }
-
-    public void processMessage(MidiMessage message) {
-        if (message instanceof ShortMessage) {
-            ShortMessage sms = (ShortMessage)message;
-            processMessage(sms.getChannel(), sms.getCommand(),
-                    sms.getData1(), sms.getData2());
-            return;
-        }
-        processMessage(message.getMessage());
-    }
-
-    public void processMessage(byte[] data) {
-        int status = 0;
-        if (data.length > 0)
-            status = data[0] & 0xFF;
-
-        if (status == 0xF0) {
-            processSystemExclusiveMessage(data);
-            return;
-        }
-
-        int cmd = (status & 0xF0);
-        int ch = (status & 0x0F);
-
-        int data1;
-        int data2;
-        if (data.length > 1)
-            data1 = data[1] & 0xFF;
-        else
-            data1 = 0;
-        if (data.length > 2)
-            data2 = data[2] & 0xFF;
-        else
-            data2 = 0;
-
-        processMessage(ch, cmd, data1, data2);
-
-    }
-
-    public void processMessage(int ch, int cmd, int data1, int data2) {
-        synchronized (synth.control_mutex) {
-            msec_last_activity = msec_pos;
-        }
-
-        if (cmd == 0xF0) {
-            int status = cmd | ch;
-            switch (status) {
-            case ShortMessage.ACTIVE_SENSING:
-                synchronized (synth.control_mutex) {
-                    active_sensing_on = true;
-                }
-                break;
-            default:
-                break;
-            }
-            return;
-        }
-
-        SoftChannel[] channels = synth.channels;
-        if (ch >= channels.length)
-            return;
-        SoftChannel softchannel = channels[ch];
-
-        switch (cmd) {
-        case ShortMessage.NOTE_ON:
-            softchannel.noteOn(data1, data2);
-            break;
-        case ShortMessage.NOTE_OFF:
-            softchannel.noteOff(data1, data2);
-            break;
-        case ShortMessage.POLY_PRESSURE:
-            softchannel.setPolyPressure(data1, data2);
-            break;
-        case ShortMessage.CONTROL_CHANGE:
-            softchannel.controlChange(data1, data2);
-            break;
-        case ShortMessage.PROGRAM_CHANGE:
-            softchannel.programChange(data1);
-            break;
-        case ShortMessage.CHANNEL_PRESSURE:
-            softchannel.setChannelPressure(data1);
-            break;
-        case ShortMessage.PITCH_BEND:
-            softchannel.setPitchBend(data1 + data2 * 128);
-            break;
-        default:
-            break;
-        }
-
-    }
-
-    public long getMicrosecondPosition() {
-        return msec_pos;
-    }
-
-    public void close() {
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Patch;
+import javax.sound.midi.ShortMessage;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+
+/**
+ * Software synthesizer main audio mixer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftMainMixer {
+
+    public final static int CHANNEL_LEFT = 0;
+    public final static int CHANNEL_RIGHT = 1;
+    public final static int CHANNEL_EFFECT1 = 2;
+    public final static int CHANNEL_EFFECT2 = 3;
+    public final static int CHANNEL_EFFECT3 = 4;
+    public final static int CHANNEL_EFFECT4 = 5;
+    public final static int CHANNEL_LEFT_DRY = 10;
+    public final static int CHANNEL_RIGHT_DRY = 11;
+    public final static int CHANNEL_SCRATCH1 = 12;
+    public final static int CHANNEL_SCRATCH2 = 13;
+    public final static int CHANNEL_CHANNELMIXER_LEFT = 14;
+    public final static int CHANNEL_CHANNELMIXER_RIGHT = 15;
+    protected boolean active_sensing_on = false;
+    protected long msec_last_activity = -1;
+    protected long msec_pos = 0;
+    protected boolean readfully = true;
+    private Object control_mutex;
+    private SoftSynthesizer synth;
+    private int nrofchannels = 2;
+    private SoftVoice[] voicestatus = null;
+    private SoftAudioBuffer[] buffers;
+    private SoftAudioProcessor reverb;
+    private SoftAudioProcessor chorus;
+    private SoftAudioProcessor agc;
+    private long msec_buffer_len = 0;
+    protected TreeMap<Long, Object> midimessages = new TreeMap<Long, Object>();
+    double finetuning = 0;
+    double coarsetuning = 0;
+    double last_volume_left = 1.0;
+    double last_volume_right = 1.0;
+    private double[] co_master_balance = new double[1];
+    private double[] co_master_volume = new double[1];
+    private double[] co_master_coarse_tuning = new double[1];
+    private double[] co_master_fine_tuning = new double[1];
+    private AudioInputStream ais;
+    private Set<ModelChannelMixer> registeredMixers = null;
+    private Set<ModelChannelMixer> stoppedMixers = null;
+    private ModelChannelMixer[] cur_registeredMixers = null;
+    protected SoftControl co_master = new SoftControl() {
+
+        double[] balance = co_master_balance;
+        double[] volume = co_master_volume;
+        double[] coarse_tuning = co_master_coarse_tuning;
+        double[] fine_tuning = co_master_fine_tuning;
+
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("balance"))
+                return balance;
+            if (name.equals("volume"))
+                return volume;
+            if (name.equals("coarse_tuning"))
+                return coarse_tuning;
+            if (name.equals("fine_tuning"))
+                return fine_tuning;
+            return null;
+        }
+    };
+
+    private void processSystemExclusiveMessage(byte[] data) {
+        synchronized (synth.control_mutex) {
+            msec_last_activity = msec_pos;
+
+            // Universal Non-Real-Time SysEx
+            if ((data[1] & 0xFF) == 0x7E) {
+                int deviceID = data[2] & 0xFF;
+                if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
+                    int subid1 = data[3] & 0xFF;
+                    int subid2;
+                    switch (subid1) {
+                    case 0x08:  // MIDI Tuning Standard
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01:  // BULK TUNING DUMP
+                        {
+                            // http://www.midi.org/about-midi/tuning.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(0,
+                                    data[5] & 0xFF));
+                            tuning.load(data);
+                            break;
+                        }
+                        case 0x04:  // KEY-BASED TUNING DUMP
+                        case 0x05:  // SCALE/OCTAVE TUNING DUMP, 1 byte format
+                        case 0x06:  // SCALE/OCTAVE TUNING DUMP, 2 byte format
+                        case 0x07:  // SINGLE NOTE TUNING CHANGE (NON REAL-TIME)
+                                    // (BANK)
+                        {
+                            // http://www.midi.org/about-midi/tuning_extens.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(
+                                    data[5] & 0xFF, data[6] & 0xFF));
+                            tuning.load(data);
+                            break;
+                        }
+                        case 0x08:  // scale/octave tuning 1-byte form (Non
+                                    // Real-Time)
+                        case 0x09:  // scale/octave tuning 2-byte form (Non
+                                    // Real-Time)
+                        {
+                            // http://www.midi.org/about-midi/tuning-scale.shtml
+                            SoftTuning tuning = new SoftTuning(data);
+                            int channelmask = (data[5] & 0xFF) * 16384
+                                    + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
+                            SoftChannel[] channels = synth.channels;
+                            for (int i = 0; i < channels.length; i++)
+                                if ((channelmask & (1 << i)) != 0)
+                                    channels[i].tuning = tuning;
+                            break;
+                        }
+                        default:
+                            break;
+                        }
+                        break;
+                    case 0x09:  // General Midi Message
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01:  // General Midi 1 On
+                            synth.setGeneralMidiMode(1);
+                            reset();
+                            break;
+                        case 0x02:  // General Midi Off
+                            synth.setGeneralMidiMode(0);
+                            reset();
+                            break;
+                        case 0x03:  // General MidI Level 2 On
+                            synth.setGeneralMidiMode(2);
+                            reset();
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+                    case 0x0A: // DLS Message
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01:  // DLS On
+                            if (synth.getGeneralMidiMode() == 0)
+                                synth.setGeneralMidiMode(1);
+                            synth.voice_allocation_mode = 1;
+                            reset();
+                            break;
+                        case 0x02:  // DLS Off
+                            synth.setGeneralMidiMode(0);
+                            synth.voice_allocation_mode = 0;
+                            reset();
+                            break;
+                        case 0x03:  // DLS Static Voice Allocation Off
+                            synth.voice_allocation_mode = 0;
+                            break;
+                        case 0x04:  // DLS Static Voice Allocation On
+                            synth.voice_allocation_mode = 1;
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+
+                    default:
+                        break;
+                    }
+                }
+            }
+
+            // Universal Real-Time SysEx
+            if ((data[1] & 0xFF) == 0x7F) {
+                int deviceID = data[2] & 0xFF;
+                if (deviceID == 0x7F || deviceID == synth.getDeviceID()) {
+                    int subid1 = data[3] & 0xFF;
+                    int subid2;
+                    switch (subid1) {
+                    case 0x04: // Device Control
+
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01: // Master Volume
+                        case 0x02: // Master Balane
+                        case 0x03: // Master fine tuning
+                        case 0x04: // Master coarse tuning
+                            int val = (data[5] & 0x7F)
+                                    + ((data[6] & 0x7F) * 128);
+                            if (subid2 == 0x01)
+                                setVolume(val);
+                            else if (subid2 == 0x02)
+                                setBalance(val);
+                            else if (subid2 == 0x03)
+                                setFineTuning(val);
+                            else if (subid2 == 0x04)
+                                setCoarseTuning(val);
+                            break;
+                        case 0x05: // Global Parameter Control
+                            int ix = 5;
+                            int slotPathLen = (data[ix++] & 0xFF);
+                            int paramWidth = (data[ix++] & 0xFF);
+                            int valueWidth = (data[ix++] & 0xFF);
+                            int[] slotPath = new int[slotPathLen];
+                            for (int i = 0; i < slotPathLen; i++) {
+                                int msb = (data[ix++] & 0xFF);
+                                int lsb = (data[ix++] & 0xFF);
+                                slotPath[i] = msb * 128 + lsb;
+                            }
+                            int paramCount = (data.length - 1 - ix)
+                                    / (paramWidth + valueWidth);
+                            long[] params = new long[paramCount];
+                            long[] values = new long[paramCount];
+                            for (int i = 0; i < paramCount; i++) {
+                                values[i] = 0;
+                                for (int j = 0; j < paramWidth; j++)
+                                    params[i] = params[i] * 128
+                                            + (data[ix++] & 0xFF);
+                                for (int j = 0; j < valueWidth; j++)
+                                    values[i] = values[i] * 128
+                                            + (data[ix++] & 0xFF);
+
+                            }
+                            globalParameterControlChange(slotPath, params, values);
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+
+                    case 0x08:  // MIDI Tuning Standard
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x02:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
+                        {
+                            // http://www.midi.org/about-midi/tuning.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(0,
+                                    data[5] & 0xFF));
+                            tuning.load(data);
+                            SoftVoice[] voices = synth.getVoices();
+                            for (int i = 0; i < voices.length; i++)
+                                if (voices[i].active)
+                                    if (voices[i].tuning == tuning)
+                                        voices[i].updateTuning(tuning);
+                            break;
+                        }
+                        case 0x07:  // SINGLE NOTE TUNING CHANGE (REAL-TIME)
+                                    // (BANK)
+                        {
+                            // http://www.midi.org/about-midi/tuning_extens.shtml
+                            SoftTuning tuning = synth.getTuning(new Patch(
+                                    data[5] & 0xFF, data[6] & 0xFF));
+                            tuning.load(data);
+                            SoftVoice[] voices = synth.getVoices();
+                            for (int i = 0; i < voices.length; i++)
+                                if (voices[i].active)
+                                    if (voices[i].tuning == tuning)
+                                        voices[i].updateTuning(tuning);
+                            break;
+                        }
+                        case 0x08:  // scale/octave tuning 1-byte form
+                                    //(Real-Time)
+                        case 0x09:  // scale/octave tuning 2-byte form
+                                    // (Real-Time)
+                        {
+                            // http://www.midi.org/about-midi/tuning-scale.shtml
+                            SoftTuning tuning = new SoftTuning(data);
+                            int channelmask = (data[5] & 0xFF) * 16384
+                                    + (data[6] & 0xFF) * 128 + (data[7] & 0xFF);
+                            SoftChannel[] channels = synth.channels;
+                            for (int i = 0; i < channels.length; i++)
+                                if ((channelmask & (1 << i)) != 0)
+                                    channels[i].tuning = tuning;
+                            SoftVoice[] voices = synth.getVoices();
+                            for (int i = 0; i < voices.length; i++)
+                                if (voices[i].active)
+                                    if ((channelmask & (1 << (voices[i].channel))) != 0)
+                                        voices[i].updateTuning(tuning);
+                            break;
+                        }
+                        default:
+                            break;
+                        }
+                        break;
+                    case 0x09:  // Control Destination Settings
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01: // Channel Pressure
+                        {
+                            int[] destinations = new int[(data.length - 7) / 2];
+                            int[] ranges = new int[(data.length - 7) / 2];
+                            int ix = 0;
+                            for (int j = 6; j < data.length - 1; j += 2) {
+                                destinations[ix] = data[j] & 0xFF;
+                                ranges[ix] = data[j + 1] & 0xFF;
+                                ix++;
+                            }
+                            int channel = data[5] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            softchannel.mapChannelPressureToDestination(
+                                    destinations, ranges);
+                            break;
+                        }
+                        case 0x02: // Poly Pressure
+                        {
+                            int[] destinations = new int[(data.length - 7) / 2];
+                            int[] ranges = new int[(data.length - 7) / 2];
+                            int ix = 0;
+                            for (int j = 6; j < data.length - 1; j += 2) {
+                                destinations[ix] = data[j] & 0xFF;
+                                ranges[ix] = data[j + 1] & 0xFF;
+                                ix++;
+                            }
+                            int channel = data[5] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            softchannel.mapPolyPressureToDestination(
+                                    destinations, ranges);
+                            break;
+                        }
+                        case 0x03: // Control Change
+                        {
+                            int[] destinations = new int[(data.length - 7) / 2];
+                            int[] ranges = new int[(data.length - 7) / 2];
+                            int ix = 0;
+                            for (int j = 7; j < data.length - 1; j += 2) {
+                                destinations[ix] = data[j] & 0xFF;
+                                ranges[ix] = data[j + 1] & 0xFF;
+                                ix++;
+                            }
+                            int channel = data[5] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            int control = data[6] & 0xFF;
+                            softchannel.mapControlToDestination(control,
+                                    destinations, ranges);
+                            break;
+                        }
+                        default:
+                            break;
+                        }
+                        break;
+
+                    case 0x0A:  // Key Based Instrument Control
+                    {
+                        subid2 = data[4] & 0xFF;
+                        switch (subid2) {
+                        case 0x01: // Basic Message
+                            int channel = data[5] & 0xFF;
+                            int keynumber = data[6] & 0xFF;
+                            SoftChannel softchannel = synth.channels[channel];
+                            for (int j = 7; j < data.length - 1; j += 2) {
+                                int controlnumber = data[j] & 0xFF;
+                                int controlvalue = data[j + 1] & 0xFF;
+                                softchannel.controlChangePerNote(keynumber,
+                                        controlnumber, controlvalue);
+                            }
+                            break;
+                        default:
+                            break;
+                        }
+                        break;
+                    }
+                    default:
+                        break;
+                    }
+                }
+            }
+
+        }
+    }
+
+    private void processMessages(long timeStamp) {
+        Iterator<Entry<Long, Object>> iter = midimessages.entrySet().iterator();
+        while (iter.hasNext()) {
+            Entry<Long, Object> entry = iter.next();
+            if (entry.getKey() > (timeStamp + 100))
+                return;
+            processMessage(entry.getValue());
+            iter.remove();
+        }
+    }
+
+    protected void processAudioBuffers() {
+        for (int i = 0; i < buffers.length; i++) {
+            buffers[i].clear();
+        }
+
+        double volume_left;
+        double volume_right;
+
+        ModelChannelMixer[] act_registeredMixers;
+
+        // perform control logic
+        synchronized (control_mutex) {
+
+            processMessages(msec_pos);
+
+            if (active_sensing_on) {
+                // Active Sensing
+                // if no message occurs for max 1000 ms
+                // then do AllSoundOff on all channels
+                if ((msec_pos - msec_last_activity) > 1000000) {
+                    active_sensing_on = false;
+                    for (SoftChannel c : synth.channels)
+                        c.allSoundOff();
+                }
+
+            }
+
+            for (int i = 0; i < voicestatus.length; i++)
+                if (voicestatus[i].active)
+                    voicestatus[i].processControlLogic();
+            msec_pos += msec_buffer_len;
+
+            double volume = co_master_volume[0];
+            volume_left = volume;
+            volume_right = volume;
+
+            double balance = co_master_balance[0];
+            if (balance > 0.5)
+                volume_left *= (1 - balance) * 2;
+            else
+                volume_right *= balance * 2;
+
+            chorus.processControlLogic();
+            reverb.processControlLogic();
+            agc.processControlLogic();
+
+            if (cur_registeredMixers == null) {
+                if (registeredMixers != null) {
+                    cur_registeredMixers =
+                            new ModelChannelMixer[registeredMixers.size()];
+                    registeredMixers.toArray(cur_registeredMixers);
+                }
+            }
+
+            act_registeredMixers = cur_registeredMixers;
+            if (act_registeredMixers != null)
+                if (act_registeredMixers.length == 0)
+                    act_registeredMixers = null;
+
+        }
+
+        if (act_registeredMixers != null) {
+
+            // Reroute default left,right output
+            // to channelmixer left,right input/output
+            SoftAudioBuffer leftbak = buffers[CHANNEL_LEFT];
+            SoftAudioBuffer rightbak = buffers[CHANNEL_RIGHT];
+            buffers[CHANNEL_LEFT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
+            buffers[CHANNEL_RIGHT] = buffers[CHANNEL_CHANNELMIXER_LEFT];
+
+            int bufferlen = buffers[CHANNEL_LEFT].getSize();
+
+            float[][] cbuffer = new float[nrofchannels][];
+            cbuffer[0] = buffers[CHANNEL_LEFT].array();
+            if (nrofchannels != 1)
+                cbuffer[1] = buffers[CHANNEL_RIGHT].array();
+
+            float[][] obuffer = new float[nrofchannels][];
+            obuffer[0] = leftbak.array();
+            if (nrofchannels != 1)
+                obuffer[1] = rightbak.array();
+
+            for (ModelChannelMixer cmixer : act_registeredMixers) {
+                for (int i = 0; i < cbuffer.length; i++)
+                    Arrays.fill(cbuffer[i], 0);
+                boolean hasactivevoices = false;
+                for (int i = 0; i < voicestatus.length; i++)
+                    if (voicestatus[i].active)
+                        if (voicestatus[i].channelmixer == cmixer) {
+                            voicestatus[i].processAudioLogic(buffers);
+                            hasactivevoices = true;
+                        }
+                if (!cmixer.process(cbuffer, 0, bufferlen)) {
+                    synchronized (control_mutex) {
+                        registeredMixers.remove(cmixer);
+                        cur_registeredMixers = null;
+                    }
+                }
+
+                for (int i = 0; i < cbuffer.length; i++) {
+                    float[] cbuff = cbuffer[i];
+                    float[] obuff = obuffer[i];
+                    for (int j = 0; j < bufferlen; j++)
+                        obuff[j] += cbuff[j];
+                }
+
+                if (!hasactivevoices) {
+                    synchronized (control_mutex) {
+                        if (stoppedMixers != null) {
+                            if (stoppedMixers.contains(cmixer)) {
+                                stoppedMixers.remove(cmixer);
+                                cmixer.stop();
+                            }
+                        }
+                    }
+                }
+
+            }
+
+            buffers[CHANNEL_LEFT] = leftbak;
+            buffers[CHANNEL_RIGHT] = rightbak;
+
+        }
+
+        for (int i = 0; i < voicestatus.length; i++)
+            if (voicestatus[i].active)
+                if (voicestatus[i].channelmixer == null)
+                    voicestatus[i].processAudioLogic(buffers);
+
+        // Run effects
+        if (synth.chorus_on)
+            chorus.processAudio();
+
+        if (synth.reverb_on)
+            reverb.processAudio();
+
+        if (nrofchannels == 1)
+            volume_left = (volume_left + volume_right) / 2;
+
+        // Set Volume / Balance
+        if (last_volume_left != volume_left || last_volume_right != volume_right) {
+            float[] left = buffers[CHANNEL_LEFT].array();
+            float[] right = buffers[CHANNEL_RIGHT].array();
+            int bufferlen = buffers[CHANNEL_LEFT].getSize();
+
+            float amp;
+            float amp_delta;
+            amp = (float)(last_volume_left * last_volume_left);
+            amp_delta = (float)((volume_left * volume_left - amp) / bufferlen);
+            for (int i = 0; i < bufferlen; i++) {
+                amp += amp_delta;
+                left[i] *= amp;
+            }
+            if (nrofchannels != 1) {
+                amp = (float)(last_volume_right * last_volume_right);
+                amp_delta = (float)((volume_right*volume_right - amp) / bufferlen);
+                for (int i = 0; i < bufferlen; i++) {
+                    amp += amp_delta;
+                    right[i] *= volume_right;
+                }
+            }
+            last_volume_left = volume_left;
+            last_volume_right = volume_right;
+
+        } else {
+            if (volume_left != 1.0 || volume_right != 1.0) {
+                float[] left = buffers[CHANNEL_LEFT].array();
+                float[] right = buffers[CHANNEL_RIGHT].array();
+                int bufferlen = buffers[CHANNEL_LEFT].getSize();
+                float amp;
+                amp = (float) (volume_left * volume_left);
+                for (int i = 0; i < bufferlen; i++)
+                    left[i] *= amp;
+                if (nrofchannels != 1) {
+                    amp = (float)(volume_right * volume_right);
+                    for (int i = 0; i < bufferlen; i++)
+                        right[i] *= amp;
+                }
+
+            }
+        }
+
+        if (synth.agc_on)
+            agc.processAudio();
+
+    }
+
+    public void stopMixer(ModelChannelMixer mixer) {
+        if (stoppedMixers == null)
+            stoppedMixers = new HashSet<ModelChannelMixer>();
+        stoppedMixers.add(mixer);
+    }
+
+    public void registerMixer(ModelChannelMixer mixer) {
+        if (registeredMixers == null)
+            registeredMixers = new HashSet<ModelChannelMixer>();
+        registeredMixers.add(mixer);
+        cur_registeredMixers = null;
+    }
+
+    public SoftMainMixer(SoftSynthesizer synth) {
+        this.synth = synth;
+
+        msec_pos = 0;
+
+        co_master_balance[0] = 0.5;
+        co_master_volume[0] = 1;
+        co_master_coarse_tuning[0] = 0.5;
+        co_master_fine_tuning[0] = 0.5;
+
+        msec_buffer_len = (long) (1000000.0 / synth.getControlRate());
+
+        nrofchannels = synth.getFormat().getChannels();
+
+        int buffersize = (int) (synth.getFormat().getSampleRate()
+                                / synth.getControlRate());
+
+        control_mutex = synth.control_mutex;
+        buffers = new SoftAudioBuffer[16];
+        for (int i = 0; i < buffers.length; i++) {
+            buffers[i] = new SoftAudioBuffer(buffersize, synth.getFormat());
+        }
+        voicestatus = synth.getVoices();
+
+        reverb = new SoftReverb();
+        chorus = new SoftChorus();
+        agc = new SoftLimiter();
+
+        reverb.init(synth);
+        chorus.init(synth);
+        agc.init(synth);
+
+        reverb.setMixMode(true);
+        chorus.setMixMode(true);
+        agc.setMixMode(false);
+
+        chorus.setInput(0, buffers[CHANNEL_EFFECT2]);
+        chorus.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            chorus.setOutput(1, buffers[CHANNEL_RIGHT]);
+        chorus.setOutput(2, buffers[CHANNEL_EFFECT1]);
+
+        reverb.setInput(0, buffers[CHANNEL_EFFECT1]);
+        reverb.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            reverb.setOutput(1, buffers[CHANNEL_RIGHT]);
+
+        agc.setInput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            agc.setInput(1, buffers[CHANNEL_RIGHT]);
+        agc.setOutput(0, buffers[CHANNEL_LEFT]);
+        if (nrofchannels != 1)
+            agc.setOutput(1, buffers[CHANNEL_RIGHT]);
+
+        InputStream in = new InputStream() {
+
+            private SoftAudioBuffer[] buffers = SoftMainMixer.this.buffers;
+            private int nrofchannels
+                    = SoftMainMixer.this.synth.getFormat().getChannels();
+            private int buffersize = buffers[0].getSize();
+            private byte[] bbuffer = new byte[buffersize
+                    * (SoftMainMixer.this.synth.getFormat()
+                        .getSampleSizeInBits() / 8)
+                    * nrofchannels];
+            private int bbuffer_pos = 0;
+            private byte[] single = new byte[1];
+
+            public void fillBuffer() {
+                processAudioBuffers();
+                for (int i = 0; i < nrofchannels; i++)
+                    buffers[i].get(bbuffer, i);
+                bbuffer_pos = 0;
+            }
+
+            public int read(byte[] b, int off, int len) {
+                int bbuffer_len = bbuffer.length;
+                int offlen = off + len;
+                int orgoff = off;
+                byte[] bbuffer = this.bbuffer;
+                while (off < offlen) {
+                    if (available() == 0)
+                        fillBuffer();
+                    else {
+                        int bbuffer_pos = this.bbuffer_pos;
+                        while (off < offlen && bbuffer_pos < bbuffer_len)
+                            b[off++] = bbuffer[bbuffer_pos++];
+                        this.bbuffer_pos = bbuffer_pos;
+                        if (!readfully)
+                            return off - orgoff;
+                    }
+                }
+                return len;
+            }
+
+            public int read() throws IOException {
+                int ret = read(single);
+                if (ret == -1)
+                    return -1;
+                return single[0] & 0xFF;
+            }
+
+            public int available() {
+                return bbuffer.length - bbuffer_pos;
+            }
+
+            public void close() {
+                SoftMainMixer.this.synth.close();
+            }
+        };
+
+        ais = new AudioInputStream(in, synth.getFormat(), AudioSystem.NOT_SPECIFIED);
+
+    }
+
+    public AudioInputStream getInputStream() {
+        return ais;
+    }
+
+    public void reset() {
+
+        SoftChannel[] channels = synth.channels;
+        for (int i = 0; i < channels.length; i++) {
+            channels[i].allSoundOff();
+            channels[i].resetAllControllers(true);
+
+            if (synth.getGeneralMidiMode() == 2) {
+                if (i == 9)
+                    channels[i].programChange(0, 0x78 * 128);
+                else
+                    channels[i].programChange(0, 0x79 * 128);
+            } else
+                channels[i].programChange(0, 0);
+        }
+        setVolume(0x7F * 128 + 0x7F);
+        setBalance(0x40 * 128 + 0x00);
+        setCoarseTuning(0x40 * 128 + 0x00);
+        setFineTuning(0x40 * 128 + 0x00);
+        // Reset Reverb
+        globalParameterControlChange(
+                new int[]{0x01 * 128 + 0x01}, new long[]{0}, new long[]{4});
+        // Reset Chorus
+        globalParameterControlChange(
+                new int[]{0x01 * 128 + 0x02}, new long[]{0}, new long[]{2});
+    }
+
+    public void setVolume(int value) {
+        synchronized (control_mutex) {
+            co_master_volume[0] = value / 16384.0;
+        }
+    }
+
+    public void setBalance(int value) {
+        synchronized (control_mutex) {
+            co_master_balance[0] = value / 16384.0;
+        }
+    }
+
+    public void setFineTuning(int value) {
+        synchronized (control_mutex) {
+            co_master_fine_tuning[0] = value / 16384.0;
+        }
+    }
+
+    public void setCoarseTuning(int value) {
+        synchronized (control_mutex) {
+            co_master_coarse_tuning[0] = value / 16384.0;
+        }
+    }
+
+    public int getVolume() {
+        synchronized (control_mutex) {
+            return (int) (co_master_volume[0] * 16384.0);
+        }
+    }
+
+    public int getBalance() {
+        synchronized (control_mutex) {
+            return (int) (co_master_balance[0] * 16384.0);
+        }
+    }
+
+    public int getFineTuning() {
+        synchronized (control_mutex) {
+            return (int) (co_master_fine_tuning[0] * 16384.0);
+        }
+    }
+
+    public int getCoarseTuning() {
+        synchronized (control_mutex) {
+            return (int) (co_master_coarse_tuning[0] * 16384.0);
+        }
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long[] params,
+            long[] paramsvalue) {
+        if (slothpath.length == 0)
+            return;
+
+        synchronized (control_mutex) {
+
+            // slothpath: 01xx are reserved only for GM2
+
+            if (slothpath[0] == 0x01 * 128 + 0x01) {
+                for (int i = 0; i < paramsvalue.length; i++) {
+                    reverb.globalParameterControlChange(slothpath, params[i],
+                            paramsvalue[i]);
+                }
+            }
+            if (slothpath[0] == 0x01 * 128 + 0x02) {
+                for (int i = 0; i < paramsvalue.length; i++) {
+                    chorus.globalParameterControlChange(slothpath, params[i],
+                            paramsvalue[i]);
+                }
+
+            }
+
+        }
+    }
+
+    public void processMessage(Object object) {
+        if (object instanceof byte[])
+            processMessage((byte[]) object);
+        if (object instanceof MidiMessage)
+            processMessage((MidiMessage)object);
+    }
+
+    public void processMessage(MidiMessage message) {
+        if (message instanceof ShortMessage) {
+            ShortMessage sms = (ShortMessage)message;
+            processMessage(sms.getChannel(), sms.getCommand(),
+                    sms.getData1(), sms.getData2());
+            return;
+        }
+        processMessage(message.getMessage());
+    }
+
+    public void processMessage(byte[] data) {
+        int status = 0;
+        if (data.length > 0)
+            status = data[0] & 0xFF;
+
+        if (status == 0xF0) {
+            processSystemExclusiveMessage(data);
+            return;
+        }
+
+        int cmd = (status & 0xF0);
+        int ch = (status & 0x0F);
+
+        int data1;
+        int data2;
+        if (data.length > 1)
+            data1 = data[1] & 0xFF;
+        else
+            data1 = 0;
+        if (data.length > 2)
+            data2 = data[2] & 0xFF;
+        else
+            data2 = 0;
+
+        processMessage(ch, cmd, data1, data2);
+
+    }
+
+    public void processMessage(int ch, int cmd, int data1, int data2) {
+        synchronized (synth.control_mutex) {
+            msec_last_activity = msec_pos;
+        }
+
+        if (cmd == 0xF0) {
+            int status = cmd | ch;
+            switch (status) {
+            case ShortMessage.ACTIVE_SENSING:
+                synchronized (synth.control_mutex) {
+                    active_sensing_on = true;
+                }
+                break;
+            default:
+                break;
+            }
+            return;
+        }
+
+        SoftChannel[] channels = synth.channels;
+        if (ch >= channels.length)
+            return;
+        SoftChannel softchannel = channels[ch];
+
+        switch (cmd) {
+        case ShortMessage.NOTE_ON:
+            softchannel.noteOn(data1, data2);
+            break;
+        case ShortMessage.NOTE_OFF:
+            softchannel.noteOff(data1, data2);
+            break;
+        case ShortMessage.POLY_PRESSURE:
+            softchannel.setPolyPressure(data1, data2);
+            break;
+        case ShortMessage.CONTROL_CHANGE:
+            softchannel.controlChange(data1, data2);
+            break;
+        case ShortMessage.PROGRAM_CHANGE:
+            softchannel.programChange(data1);
+            break;
+        case ShortMessage.CHANNEL_PRESSURE:
+            softchannel.setChannelPressure(data1);
+            break;
+        case ShortMessage.PITCH_BEND:
+            softchannel.setPitchBend(data1 + data2 * 128);
+            break;
+        default:
+            break;
+        }
+
+    }
+
+    public long getMicrosecondPosition() {
+        return msec_pos;
+    }
+
+    public void close() {
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftPerformer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftPerformer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,775 +1,775 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class decodes information from ModelPeformer for use in SoftVoice.
- * It also adds default connections if they where missing in ModelPerformer.
- *
- * @author Karl Helgason
- */
-public class SoftPerformer {
-
-    static ModelConnectionBlock[] defaultconnections
-            = new ModelConnectionBlock[42];
-
-    static {
-        int o = 0;
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("noteon", "on", 0),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1, new ModelDestination(new ModelIdentifier("eg", "on", 0)));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("noteon", "on", 0),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1, new ModelDestination(new ModelIdentifier("eg", "on", 1)));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("eg", "active", 0),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1, new ModelDestination(new ModelIdentifier("mixer", "active", 0)));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("eg", 0),
-                ModelStandardTransform.DIRECTION_MAX2MIN,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("noteon", "velocity"),
-                ModelStandardTransform.DIRECTION_MAX2MIN,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_CONCAVE),
-            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi", "pitch"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            new ModelSource(new ModelIdentifier("midi_rpn", "0"),
-                new ModelTransform() {
-                    public double transform(double value) {
-                        int v = (int) (value * 16384.0);
-                        int msb = v >> 7;
-                        int lsb = v & 127;
-                        return msb * 100 + lsb;
-                    }
-                }),
-            new ModelDestination(new ModelIdentifier("osc", "pitch")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("noteon", "keynumber"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "7"),
-                ModelStandardTransform.DIRECTION_MAX2MIN,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_CONCAVE),
-            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "8"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1000, new ModelDestination(new ModelIdentifier("mixer", "balance")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "10"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1000, new ModelDestination(new ModelIdentifier("mixer", "pan")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "11"),
-                ModelStandardTransform.DIRECTION_MAX2MIN,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_CONCAVE),
-            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "91"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1000, new ModelDestination(new ModelIdentifier("mixer", "reverb")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "93"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            1000, new ModelDestination(new ModelIdentifier("mixer", "chorus")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "71"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            200, new ModelDestination(new ModelIdentifier("filter", "q")));
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "74"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            9600, new ModelDestination(new ModelIdentifier("filter", "freq")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "72"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            6000, new ModelDestination(new ModelIdentifier("eg", "release2")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "73"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            2000, new ModelDestination(new ModelIdentifier("eg", "attack2")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "75"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            6000, new ModelDestination(new ModelIdentifier("eg", "decay2")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "67"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_SWITCH),
-            -50, new ModelDestination(ModelDestination.DESTINATION_GAIN));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_cc", "67"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_UNIPOLAR,
-                ModelStandardTransform.TRANSFORM_SWITCH),
-            -2400, new ModelDestination(ModelDestination.DESTINATION_FILTER_FREQ));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_rpn", "1"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("midi_rpn", "2"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("master", "fine_tuning"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-            new ModelSource(
-                new ModelIdentifier("master", "coarse_tuning"),
-                ModelStandardTransform.DIRECTION_MIN2MAX,
-                ModelStandardTransform.POLARITY_BIPOLAR,
-                ModelStandardTransform.TRANSFORM_LINEAR),
-            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
-
-        defaultconnections[o++] = new ModelConnectionBlock(13500,
-                new ModelDestination(new ModelIdentifier("filter", "freq", 0)));
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "delay", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "attack", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "hold", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "decay", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(1000,
-                new ModelDestination(new ModelIdentifier("eg", "sustain", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "release", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(1200.0
-                * Math.log(0.015) / Math.log(2), new ModelDestination(
-                new ModelIdentifier("eg", "shutdown", 0))); // 15 msec default
-
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "delay", 1)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "attack", 1)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "hold", 1)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "decay", 1)));
-        defaultconnections[o++] = new ModelConnectionBlock(1000,
-                new ModelDestination(new ModelIdentifier("eg", "sustain", 1)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("eg", "release", 1)));
-
-        defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
-                new ModelDestination(new ModelIdentifier("lfo", "freq", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("lfo", "delay", 0)));
-        defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
-                new ModelDestination(new ModelIdentifier("lfo", "freq", 1)));
-        defaultconnections[o++] = new ModelConnectionBlock(
-                Float.NEGATIVE_INFINITY, new ModelDestination(
-                new ModelIdentifier("lfo", "delay", 1)));
-
-    }
-    public int keyFrom = 0;
-    public int keyTo = 127;
-    public int velFrom = 0;
-    public int velTo = 127;
-    public int exclusiveClass = 0;
-    public boolean selfNonExclusive = false;
-    public boolean forcedVelocity = false;
-    public boolean forcedKeynumber = false;
-    public ModelPerformer performer;
-    public ModelConnectionBlock[] connections;
-    public ModelOscillator[] oscillators;
-    public Map<Integer, int[]> midi_rpn_connections = new HashMap<Integer, int[]>();
-    public Map<Integer, int[]> midi_nrpn_connections = new HashMap<Integer, int[]>();
-    public int[][] midi_ctrl_connections;
-    public int[][] midi_connections;
-    public int[] ctrl_connections;
-    private List<Integer> ctrl_connections_list = new ArrayList<Integer>();
-
-    private static class KeySortComparator implements Comparator<ModelSource> {
-
-        public int compare(ModelSource o1, ModelSource o2) {
-            return o1.getIdentifier().toString().compareTo(
-                    o2.getIdentifier().toString());
-        }
-    }
-    private static KeySortComparator keySortComparator = new KeySortComparator();
-
-    private String extractKeys(ModelConnectionBlock conn) {
-        StringBuffer sb = new StringBuffer();
-        if (conn.getSources() != null) {
-            sb.append("[");
-            ModelSource[] srcs = conn.getSources();
-            ModelSource[] srcs2 = new ModelSource[srcs.length];
-            for (int i = 0; i < srcs.length; i++)
-                srcs2[i] = srcs[i];
-            Arrays.sort(srcs2, keySortComparator);
-            for (int i = 0; i < srcs.length; i++) {
-                sb.append(srcs[i].getIdentifier());
-                sb.append(";");
-            }
-            sb.append("]");
-        }
-        sb.append(";");
-        if (conn.getDestination() != null) {
-            sb.append(conn.getDestination().getIdentifier());
-        }
-        sb.append(";");
-        return sb.toString();
-    }
-
-    private void processSource(ModelSource src, int ix) {
-        ModelIdentifier id = src.getIdentifier();
-        String o = id.getObject();
-        if (o.equals("midi_cc"))
-            processMidiControlSource(src, ix);
-        else if (o.equals("midi_rpn"))
-            processMidiRpnSource(src, ix);
-        else if (o.equals("midi_nrpn"))
-            processMidiNrpnSource(src, ix);
-        else if (o.equals("midi"))
-            processMidiSource(src, ix);
-        else if (o.equals("noteon"))
-            processNoteOnSource(src, ix);
-        else if (o.equals("osc"))
-            return;
-        else if (o.equals("mixer"))
-            return;
-        else
-            ctrl_connections_list.add(ix);
-    }
-
-    private void processMidiControlSource(ModelSource src, int ix) {
-        String v = src.getIdentifier().getVariable();
-        if (v == null)
-            return;
-        int c = Integer.parseInt(v);
-        if (midi_ctrl_connections[c] == null)
-            midi_ctrl_connections[c] = new int[]{ix};
-        else {
-            int[] olda = midi_ctrl_connections[c];
-            int[] newa = new int[olda.length + 1];
-            for (int i = 0; i < olda.length; i++)
-                newa[i] = olda[i];
-            newa[newa.length - 1] = ix;
-            midi_ctrl_connections[c] = newa;
-        }
-    }
-
-    private void processNoteOnSource(ModelSource src, int ix) {
-        String v = src.getIdentifier().getVariable();
-        int c = -1;
-        if (v.equals("on"))
-            c = 3;
-        if (v.equals("keynumber"))
-            c = 4;
-        if (c == -1)
-            return;
-        if (midi_connections[c] == null)
-            midi_connections[c] = new int[]{ix};
-        else {
-            int[] olda = midi_connections[c];
-            int[] newa = new int[olda.length + 1];
-            for (int i = 0; i < olda.length; i++)
-                newa[i] = olda[i];
-            newa[newa.length - 1] = ix;
-            midi_connections[c] = newa;
-        }
-    }
-
-    private void processMidiSource(ModelSource src, int ix) {
-        String v = src.getIdentifier().getVariable();
-        int c = -1;
-        if (v.equals("pitch"))
-            c = 0;
-        if (v.equals("channel_pressure"))
-            c = 1;
-        if (v.equals("poly_pressure"))
-            c = 2;
-        if (c == -1)
-            return;
-        if (midi_connections[c] == null)
-            midi_connections[c] = new int[]{ix};
-        else {
-            int[] olda = midi_connections[c];
-            int[] newa = new int[olda.length + 1];
-            for (int i = 0; i < olda.length; i++)
-                newa[i] = olda[i];
-            newa[newa.length - 1] = ix;
-            midi_connections[c] = newa;
-        }
-    }
-
-    private void processMidiRpnSource(ModelSource src, int ix) {
-        String v = src.getIdentifier().getVariable();
-        if (v == null)
-            return;
-        int c = Integer.parseInt(v);
-        if (midi_rpn_connections.get(c) == null)
-            midi_rpn_connections.put(c, new int[]{ix});
-        else {
-            int[] olda = midi_rpn_connections.get(c);
-            int[] newa = new int[olda.length + 1];
-            for (int i = 0; i < olda.length; i++)
-                newa[i] = olda[i];
-            newa[newa.length - 1] = ix;
-            midi_rpn_connections.put(c, newa);
-        }
-    }
-
-    private void processMidiNrpnSource(ModelSource src, int ix) {
-        String v = src.getIdentifier().getVariable();
-        if (v == null)
-            return;
-        int c = Integer.parseInt(v);
-        if (midi_nrpn_connections.get(c) == null)
-            midi_nrpn_connections.put(c, new int[]{ix});
-        else {
-            int[] olda = midi_nrpn_connections.get(c);
-            int[] newa = new int[olda.length + 1];
-            for (int i = 0; i < olda.length; i++)
-                newa[i] = olda[i];
-            newa[newa.length - 1] = ix;
-            midi_nrpn_connections.put(c, newa);
-        }
-    }
-
-    public SoftPerformer(ModelPerformer performer) {
-        this.performer = performer;
-
-        keyFrom = performer.getKeyFrom();
-        keyTo = performer.getKeyTo();
-        velFrom = performer.getVelFrom();
-        velTo = performer.getVelTo();
-        exclusiveClass = performer.getExclusiveClass();
-        selfNonExclusive = performer.isSelfNonExclusive();
-
-        Map<String, ModelConnectionBlock> connmap = new HashMap<String, ModelConnectionBlock>();
-
-        List<ModelConnectionBlock> performer_connections = new ArrayList<ModelConnectionBlock>();
-        performer_connections.addAll(performer.getConnectionBlocks());
-
-        if (performer.isDefaultConnectionsEnabled()) {
-
-            // Add modulation depth range (RPN 5) to the modulation wheel (cc#1)
-
-            boolean isModulationWheelConectionFound = false;
-            for (int j = 0; j < performer_connections.size(); j++) {
-                ModelConnectionBlock connection = performer_connections.get(j);
-                ModelSource[] sources = connection.getSources();
-                ModelDestination dest = connection.getDestination();
-                boolean isModulationWheelConection = false;
-                if (dest != null && sources != null && sources.length > 1) {
-                    for (int i = 0; i < sources.length; i++) {
-                        // check if connection block has the source "modulation
-                        // wheel cc#1"
-                        if (sources[i].getIdentifier().getObject().equals(
-                                "midi_cc")) {
-                            if (sources[i].getIdentifier().getVariable()
-                                    .equals("1")) {
-                                isModulationWheelConection = true;
-                                isModulationWheelConectionFound = true;
-                                break;
-                            }
-                        }
-                    }
-                }
-                if (isModulationWheelConection) {
-
-                    ModelConnectionBlock newconnection = new ModelConnectionBlock();
-                    newconnection.setSources(connection.getSources());
-                    newconnection.setDestination(connection.getDestination());
-                    newconnection.addSource(new ModelSource(
-                            new ModelIdentifier("midi_rpn", "5")));
-                    newconnection.setScale(connection.getScale() * 256.0);
-                    performer_connections.set(j, newconnection);
-                }
-            }
-
-            if (!isModulationWheelConectionFound) {
-                ModelConnectionBlock conn = new ModelConnectionBlock(
-                        new ModelSource(ModelSource.SOURCE_LFO1,
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_BIPOLAR,
-                        ModelStandardTransform.TRANSFORM_LINEAR),
-                        new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
-                        ModelStandardTransform.DIRECTION_MIN2MAX,
-                        ModelStandardTransform.POLARITY_UNIPOLAR,
-                        ModelStandardTransform.TRANSFORM_LINEAR),
-                        50,
-                        new ModelDestination(ModelDestination.DESTINATION_PITCH));
-                conn.addSource(new ModelSource(new ModelIdentifier("midi_rpn",
-                        "5")));
-                conn.setScale(conn.getScale() * 256.0);
-                performer_connections.add(conn);
-
-            }
-
-            // Let Aftertouch to behave just like modulation wheel (cc#1)
-            boolean channel_pressure_set = false;
-            boolean poly_pressure = false;
-            ModelConnectionBlock mod_cc_1_connection = null;
-            int mod_cc_1_connection_src_ix = 0;
-
-            for (ModelConnectionBlock connection : performer_connections) {
-                ModelSource[] sources = connection.getSources();
-                ModelDestination dest = connection.getDestination();
-                // if(dest != null && sources != null)
-                if (dest != null && sources != null) {
-                    for (int i = 0; i < sources.length; i++) {
-                        ModelIdentifier srcid = sources[i].getIdentifier();
-                        // check if connection block has the source "modulation
-                        // wheel cc#1"
-                        if (srcid.getObject().equals("midi_cc")) {
-                            if (srcid.getVariable().equals("1")) {
-                                mod_cc_1_connection = connection;
-                                mod_cc_1_connection_src_ix = i;
-                            }
-                        }
-                        // check if channel or poly pressure are already
-                        // connected
-                        if (srcid.getObject().equals("midi")) {
-                            if (srcid.getVariable().equals("channel_pressure"))
-                                channel_pressure_set = true;
-                            if (srcid.getVariable().equals("poly_pressure"))
-                                poly_pressure = true;
-                        }
-                    }
-                }
-
-            }
-
-            if (mod_cc_1_connection != null) {
-                if (!channel_pressure_set) {
-                    ModelConnectionBlock mc = new ModelConnectionBlock();
-                    mc.setDestination(mod_cc_1_connection.getDestination());
-                    mc.setScale(mod_cc_1_connection.getScale());
-                    ModelSource[] src_list = mod_cc_1_connection.getSources();
-                    ModelSource[] src_list_new = new ModelSource[src_list.length];
-                    for (int i = 0; i < src_list_new.length; i++)
-                        src_list_new[i] = src_list[i];
-                    src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
-                            new ModelIdentifier("midi", "channel_pressure"));
-                    mc.setSources(src_list_new);
-                    connmap.put(extractKeys(mc), mc);
-                }
-                if (!poly_pressure) {
-                    ModelConnectionBlock mc = new ModelConnectionBlock();
-                    mc.setDestination(mod_cc_1_connection.getDestination());
-                    mc.setScale(mod_cc_1_connection.getScale());
-                    ModelSource[] src_list = mod_cc_1_connection.getSources();
-                    ModelSource[] src_list_new = new ModelSource[src_list.length];
-                    for (int i = 0; i < src_list_new.length; i++)
-                        src_list_new[i] = src_list[i];
-                    src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
-                            new ModelIdentifier("midi", "poly_pressure"));
-                    mc.setSources(src_list_new);
-                    connmap.put(extractKeys(mc), mc);
-                }
-            }
-
-            // Enable Vibration Sound Controllers : 76, 77, 78
-            ModelConnectionBlock found_vib_connection = null;
-            for (ModelConnectionBlock connection : performer_connections) {
-                ModelSource[] sources = connection.getSources();
-                if (sources.length != 0
-                        && sources[0].getIdentifier().getObject().equals("lfo")) {
-                    if (connection.getDestination().getIdentifier().equals(
-                            ModelDestination.DESTINATION_PITCH)) {
-                        if (found_vib_connection == null)
-                            found_vib_connection = connection;
-                        else {
-                            if (found_vib_connection.getSources().length > sources.length)
-                                found_vib_connection = connection;
-                            else if (found_vib_connection.getSources()[0]
-                                    .getIdentifier().getInstance() < 1) {
-                                if (found_vib_connection.getSources()[0]
-                                        .getIdentifier().getInstance() >
-                                        sources[0].getIdentifier().getInstance()) {
-                                    found_vib_connection = connection;
-                                }
-                            }
-                        }
-
-                    }
-                }
-            }
-
-            int instance = 1;
-
-            if (found_vib_connection != null) {
-                instance = found_vib_connection.getSources()[0].getIdentifier()
-                        .getInstance();
-            }
-            ModelConnectionBlock connection;
-
-            connection = new ModelConnectionBlock(
-                new ModelSource(new ModelIdentifier("midi_cc", "78"),
-                    ModelStandardTransform.DIRECTION_MIN2MAX,
-                    ModelStandardTransform.POLARITY_BIPOLAR,
-                    ModelStandardTransform.TRANSFORM_LINEAR),
-                2000, new ModelDestination(
-                    new ModelIdentifier("lfo", "delay2", instance)));
-            connmap.put(extractKeys(connection), connection);
-
-            final double scale = found_vib_connection == null ? 0
-                    : found_vib_connection.getScale();
-            connection = new ModelConnectionBlock(
-                new ModelSource(new ModelIdentifier("lfo", instance)),
-                new ModelSource(new ModelIdentifier("midi_cc", "77"),
-                    new ModelTransform() {
-                        double s = scale;
-                        public double transform(double value) {
-                            value = value * 2 - 1;
-                            value *= 600;
-                            if (s == 0) {
-                                return value;
-                            } else if (s > 0) {
-                                if (value < -s)
-                                    value = -s;
-                                return value;
-                            } else {
-                                if (value < s)
-                                    value = -s;
-                                return -value;
-                            }
-                        }
-                    }), new ModelDestination(ModelDestination.DESTINATION_PITCH));
-            connmap.put(extractKeys(connection), connection);
-
-            connection = new ModelConnectionBlock(
-                new ModelSource(new ModelIdentifier("midi_cc", "76"),
-                    ModelStandardTransform.DIRECTION_MIN2MAX,
-                    ModelStandardTransform.POLARITY_BIPOLAR,
-                    ModelStandardTransform.TRANSFORM_LINEAR),
-                2400, new ModelDestination(
-                    new ModelIdentifier("lfo", "freq", instance)));
-            connmap.put(extractKeys(connection), connection);
-
-        }
-
-        // Add default connection blocks
-        if (performer.isDefaultConnectionsEnabled())
-            for (ModelConnectionBlock connection : defaultconnections)
-                connmap.put(extractKeys(connection), connection);
-        // Add connection blocks from modelperformer
-        for (ModelConnectionBlock connection : performer_connections)
-            connmap.put(extractKeys(connection), connection);
-        // seperate connection blocks : Init time, Midi Time, Midi/Control Time,
-        // Control Time
-        List<ModelConnectionBlock> connections = new ArrayList<ModelConnectionBlock>();
-
-        midi_ctrl_connections = new int[128][];
-        for (int i = 0; i < midi_ctrl_connections.length; i++) {
-            midi_ctrl_connections[i] = null;
-        }
-        midi_connections = new int[5][];
-        for (int i = 0; i < midi_connections.length; i++) {
-            midi_connections[i] = null;
-        }
-
-        int ix = 0;
-        boolean mustBeOnTop = false;
-
-        for (ModelConnectionBlock connection : connmap.values()) {
-            if (connection.getDestination() != null) {
-                ModelDestination dest = connection.getDestination();
-                ModelIdentifier id = dest.getIdentifier();
-                if (id.getObject().equals("noteon")) {
-                    mustBeOnTop = true;
-                    if (id.getVariable().equals("keynumber"))
-                        forcedKeynumber = true;
-                    if (id.getVariable().equals("velocity"))
-                        forcedVelocity = true;
-                }
-            }
-            if (mustBeOnTop) {
-                connections.add(0, connection);
-                mustBeOnTop = false;
-            } else
-                connections.add(connection);
-        }
-
-        for (ModelConnectionBlock connection : connections) {
-            if (connection.getSources() != null) {
-                ModelSource[] srcs = connection.getSources();
-                for (int i = 0; i < srcs.length; i++) {
-                    processSource(srcs[i], ix);
-                }
-            }
-            ix++;
-        }
-
-        this.connections = new ModelConnectionBlock[connections.size()];
-        connections.toArray(this.connections);
-
-        this.ctrl_connections = new int[ctrl_connections_list.size()];
-
-        for (int i = 0; i < this.ctrl_connections.length; i++)
-            this.ctrl_connections[i] = ctrl_connections_list.get(i);
-
-        oscillators = new ModelOscillator[performer.getOscillators().size()];
-        performer.getOscillators().toArray(oscillators);
-
-        for (ModelConnectionBlock conn : connections) {
-            if (conn.getDestination() != null) {
-                if (isUnnecessaryTransform(conn.getDestination().getTransform())) {
-                    conn.getDestination().setTransform(null);
-                }
-            }
-            if (conn.getSources() != null) {
-                for (ModelSource src : conn.getSources()) {
-                    if (isUnnecessaryTransform(src.getTransform())) {
-                        src.setTransform(null);
-                    }
-                }
-            }
-        }
-
-    }
-
-    private static boolean isUnnecessaryTransform(ModelTransform transform) {
-        if (transform == null)
-            return false;
-        if (!(transform instanceof ModelStandardTransform))
-            return false;
-        ModelStandardTransform stransform = (ModelStandardTransform)transform;
-        if (stransform.getDirection() != ModelStandardTransform.DIRECTION_MIN2MAX)
-            return false;
-        if (stransform.getPolarity() != ModelStandardTransform.POLARITY_UNIPOLAR)
-            return false;
-        if (stransform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
-            return false;
-        return false;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class decodes information from ModelPeformer for use in SoftVoice.
+ * It also adds default connections if they where missing in ModelPerformer.
+ *
+ * @author Karl Helgason
+ */
+public class SoftPerformer {
+
+    static ModelConnectionBlock[] defaultconnections
+            = new ModelConnectionBlock[42];
+
+    static {
+        int o = 0;
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "on", 0),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1, new ModelDestination(new ModelIdentifier("eg", "on", 0)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "on", 0),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1, new ModelDestination(new ModelIdentifier("eg", "on", 1)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("eg", "active", 0),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1, new ModelDestination(new ModelIdentifier("mixer", "active", 0)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("eg", 0),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "velocity"),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi", "pitch"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            new ModelSource(new ModelIdentifier("midi_rpn", "0"),
+                new ModelTransform() {
+                    public double transform(double value) {
+                        int v = (int) (value * 16384.0);
+                        int msb = v >> 7;
+                        int lsb = v & 127;
+                        return msb * 100 + lsb;
+                    }
+                }),
+            new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("noteon", "keynumber"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "7"),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "8"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "balance")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "10"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "pan")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "11"),
+                ModelStandardTransform.DIRECTION_MAX2MIN,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_CONCAVE),
+            -960, new ModelDestination(new ModelIdentifier("mixer", "gain")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "91"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "reverb")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "93"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            1000, new ModelDestination(new ModelIdentifier("mixer", "chorus")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "71"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            200, new ModelDestination(new ModelIdentifier("filter", "q")));
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "74"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            9600, new ModelDestination(new ModelIdentifier("filter", "freq")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "72"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            6000, new ModelDestination(new ModelIdentifier("eg", "release2")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "73"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            2000, new ModelDestination(new ModelIdentifier("eg", "attack2")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "75"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            6000, new ModelDestination(new ModelIdentifier("eg", "decay2")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "67"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_SWITCH),
+            -50, new ModelDestination(ModelDestination.DESTINATION_GAIN));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_cc", "67"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_UNIPOLAR,
+                ModelStandardTransform.TRANSFORM_SWITCH),
+            -2400, new ModelDestination(ModelDestination.DESTINATION_FILTER_FREQ));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_rpn", "1"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("midi_rpn", "2"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("master", "fine_tuning"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            100, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+            new ModelSource(
+                new ModelIdentifier("master", "coarse_tuning"),
+                ModelStandardTransform.DIRECTION_MIN2MAX,
+                ModelStandardTransform.POLARITY_BIPOLAR,
+                ModelStandardTransform.TRANSFORM_LINEAR),
+            12800, new ModelDestination(new ModelIdentifier("osc", "pitch")));
+
+        defaultconnections[o++] = new ModelConnectionBlock(13500,
+                new ModelDestination(new ModelIdentifier("filter", "freq", 0)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "delay", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "attack", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "hold", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "decay", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(1000,
+                new ModelDestination(new ModelIdentifier("eg", "sustain", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "release", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(1200.0
+                * Math.log(0.015) / Math.log(2), new ModelDestination(
+                new ModelIdentifier("eg", "shutdown", 0))); // 15 msec default
+
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "delay", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "attack", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "hold", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "decay", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(1000,
+                new ModelDestination(new ModelIdentifier("eg", "sustain", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("eg", "release", 1)));
+
+        defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
+                new ModelDestination(new ModelIdentifier("lfo", "freq", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("lfo", "delay", 0)));
+        defaultconnections[o++] = new ModelConnectionBlock(-8.51318,
+                new ModelDestination(new ModelIdentifier("lfo", "freq", 1)));
+        defaultconnections[o++] = new ModelConnectionBlock(
+                Float.NEGATIVE_INFINITY, new ModelDestination(
+                new ModelIdentifier("lfo", "delay", 1)));
+
+    }
+    public int keyFrom = 0;
+    public int keyTo = 127;
+    public int velFrom = 0;
+    public int velTo = 127;
+    public int exclusiveClass = 0;
+    public boolean selfNonExclusive = false;
+    public boolean forcedVelocity = false;
+    public boolean forcedKeynumber = false;
+    public ModelPerformer performer;
+    public ModelConnectionBlock[] connections;
+    public ModelOscillator[] oscillators;
+    public Map<Integer, int[]> midi_rpn_connections = new HashMap<Integer, int[]>();
+    public Map<Integer, int[]> midi_nrpn_connections = new HashMap<Integer, int[]>();
+    public int[][] midi_ctrl_connections;
+    public int[][] midi_connections;
+    public int[] ctrl_connections;
+    private List<Integer> ctrl_connections_list = new ArrayList<Integer>();
+
+    private static class KeySortComparator implements Comparator<ModelSource> {
+
+        public int compare(ModelSource o1, ModelSource o2) {
+            return o1.getIdentifier().toString().compareTo(
+                    o2.getIdentifier().toString());
+        }
+    }
+    private static KeySortComparator keySortComparator = new KeySortComparator();
+
+    private String extractKeys(ModelConnectionBlock conn) {
+        StringBuffer sb = new StringBuffer();
+        if (conn.getSources() != null) {
+            sb.append("[");
+            ModelSource[] srcs = conn.getSources();
+            ModelSource[] srcs2 = new ModelSource[srcs.length];
+            for (int i = 0; i < srcs.length; i++)
+                srcs2[i] = srcs[i];
+            Arrays.sort(srcs2, keySortComparator);
+            for (int i = 0; i < srcs.length; i++) {
+                sb.append(srcs[i].getIdentifier());
+                sb.append(";");
+            }
+            sb.append("]");
+        }
+        sb.append(";");
+        if (conn.getDestination() != null) {
+            sb.append(conn.getDestination().getIdentifier());
+        }
+        sb.append(";");
+        return sb.toString();
+    }
+
+    private void processSource(ModelSource src, int ix) {
+        ModelIdentifier id = src.getIdentifier();
+        String o = id.getObject();
+        if (o.equals("midi_cc"))
+            processMidiControlSource(src, ix);
+        else if (o.equals("midi_rpn"))
+            processMidiRpnSource(src, ix);
+        else if (o.equals("midi_nrpn"))
+            processMidiNrpnSource(src, ix);
+        else if (o.equals("midi"))
+            processMidiSource(src, ix);
+        else if (o.equals("noteon"))
+            processNoteOnSource(src, ix);
+        else if (o.equals("osc"))
+            return;
+        else if (o.equals("mixer"))
+            return;
+        else
+            ctrl_connections_list.add(ix);
+    }
+
+    private void processMidiControlSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        if (v == null)
+            return;
+        int c = Integer.parseInt(v);
+        if (midi_ctrl_connections[c] == null)
+            midi_ctrl_connections[c] = new int[]{ix};
+        else {
+            int[] olda = midi_ctrl_connections[c];
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_ctrl_connections[c] = newa;
+        }
+    }
+
+    private void processNoteOnSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        int c = -1;
+        if (v.equals("on"))
+            c = 3;
+        if (v.equals("keynumber"))
+            c = 4;
+        if (c == -1)
+            return;
+        if (midi_connections[c] == null)
+            midi_connections[c] = new int[]{ix};
+        else {
+            int[] olda = midi_connections[c];
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_connections[c] = newa;
+        }
+    }
+
+    private void processMidiSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        int c = -1;
+        if (v.equals("pitch"))
+            c = 0;
+        if (v.equals("channel_pressure"))
+            c = 1;
+        if (v.equals("poly_pressure"))
+            c = 2;
+        if (c == -1)
+            return;
+        if (midi_connections[c] == null)
+            midi_connections[c] = new int[]{ix};
+        else {
+            int[] olda = midi_connections[c];
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_connections[c] = newa;
+        }
+    }
+
+    private void processMidiRpnSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        if (v == null)
+            return;
+        int c = Integer.parseInt(v);
+        if (midi_rpn_connections.get(c) == null)
+            midi_rpn_connections.put(c, new int[]{ix});
+        else {
+            int[] olda = midi_rpn_connections.get(c);
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_rpn_connections.put(c, newa);
+        }
+    }
+
+    private void processMidiNrpnSource(ModelSource src, int ix) {
+        String v = src.getIdentifier().getVariable();
+        if (v == null)
+            return;
+        int c = Integer.parseInt(v);
+        if (midi_nrpn_connections.get(c) == null)
+            midi_nrpn_connections.put(c, new int[]{ix});
+        else {
+            int[] olda = midi_nrpn_connections.get(c);
+            int[] newa = new int[olda.length + 1];
+            for (int i = 0; i < olda.length; i++)
+                newa[i] = olda[i];
+            newa[newa.length - 1] = ix;
+            midi_nrpn_connections.put(c, newa);
+        }
+    }
+
+    public SoftPerformer(ModelPerformer performer) {
+        this.performer = performer;
+
+        keyFrom = performer.getKeyFrom();
+        keyTo = performer.getKeyTo();
+        velFrom = performer.getVelFrom();
+        velTo = performer.getVelTo();
+        exclusiveClass = performer.getExclusiveClass();
+        selfNonExclusive = performer.isSelfNonExclusive();
+
+        Map<String, ModelConnectionBlock> connmap = new HashMap<String, ModelConnectionBlock>();
+
+        List<ModelConnectionBlock> performer_connections = new ArrayList<ModelConnectionBlock>();
+        performer_connections.addAll(performer.getConnectionBlocks());
+
+        if (performer.isDefaultConnectionsEnabled()) {
+
+            // Add modulation depth range (RPN 5) to the modulation wheel (cc#1)
+
+            boolean isModulationWheelConectionFound = false;
+            for (int j = 0; j < performer_connections.size(); j++) {
+                ModelConnectionBlock connection = performer_connections.get(j);
+                ModelSource[] sources = connection.getSources();
+                ModelDestination dest = connection.getDestination();
+                boolean isModulationWheelConection = false;
+                if (dest != null && sources != null && sources.length > 1) {
+                    for (int i = 0; i < sources.length; i++) {
+                        // check if connection block has the source "modulation
+                        // wheel cc#1"
+                        if (sources[i].getIdentifier().getObject().equals(
+                                "midi_cc")) {
+                            if (sources[i].getIdentifier().getVariable()
+                                    .equals("1")) {
+                                isModulationWheelConection = true;
+                                isModulationWheelConectionFound = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (isModulationWheelConection) {
+
+                    ModelConnectionBlock newconnection = new ModelConnectionBlock();
+                    newconnection.setSources(connection.getSources());
+                    newconnection.setDestination(connection.getDestination());
+                    newconnection.addSource(new ModelSource(
+                            new ModelIdentifier("midi_rpn", "5")));
+                    newconnection.setScale(connection.getScale() * 256.0);
+                    performer_connections.set(j, newconnection);
+                }
+            }
+
+            if (!isModulationWheelConectionFound) {
+                ModelConnectionBlock conn = new ModelConnectionBlock(
+                        new ModelSource(ModelSource.SOURCE_LFO1,
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_BIPOLAR,
+                        ModelStandardTransform.TRANSFORM_LINEAR),
+                        new ModelSource(new ModelIdentifier("midi_cc", "1", 0),
+                        ModelStandardTransform.DIRECTION_MIN2MAX,
+                        ModelStandardTransform.POLARITY_UNIPOLAR,
+                        ModelStandardTransform.TRANSFORM_LINEAR),
+                        50,
+                        new ModelDestination(ModelDestination.DESTINATION_PITCH));
+                conn.addSource(new ModelSource(new ModelIdentifier("midi_rpn",
+                        "5")));
+                conn.setScale(conn.getScale() * 256.0);
+                performer_connections.add(conn);
+
+            }
+
+            // Let Aftertouch to behave just like modulation wheel (cc#1)
+            boolean channel_pressure_set = false;
+            boolean poly_pressure = false;
+            ModelConnectionBlock mod_cc_1_connection = null;
+            int mod_cc_1_connection_src_ix = 0;
+
+            for (ModelConnectionBlock connection : performer_connections) {
+                ModelSource[] sources = connection.getSources();
+                ModelDestination dest = connection.getDestination();
+                // if(dest != null && sources != null)
+                if (dest != null && sources != null) {
+                    for (int i = 0; i < sources.length; i++) {
+                        ModelIdentifier srcid = sources[i].getIdentifier();
+                        // check if connection block has the source "modulation
+                        // wheel cc#1"
+                        if (srcid.getObject().equals("midi_cc")) {
+                            if (srcid.getVariable().equals("1")) {
+                                mod_cc_1_connection = connection;
+                                mod_cc_1_connection_src_ix = i;
+                            }
+                        }
+                        // check if channel or poly pressure are already
+                        // connected
+                        if (srcid.getObject().equals("midi")) {
+                            if (srcid.getVariable().equals("channel_pressure"))
+                                channel_pressure_set = true;
+                            if (srcid.getVariable().equals("poly_pressure"))
+                                poly_pressure = true;
+                        }
+                    }
+                }
+
+            }
+
+            if (mod_cc_1_connection != null) {
+                if (!channel_pressure_set) {
+                    ModelConnectionBlock mc = new ModelConnectionBlock();
+                    mc.setDestination(mod_cc_1_connection.getDestination());
+                    mc.setScale(mod_cc_1_connection.getScale());
+                    ModelSource[] src_list = mod_cc_1_connection.getSources();
+                    ModelSource[] src_list_new = new ModelSource[src_list.length];
+                    for (int i = 0; i < src_list_new.length; i++)
+                        src_list_new[i] = src_list[i];
+                    src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
+                            new ModelIdentifier("midi", "channel_pressure"));
+                    mc.setSources(src_list_new);
+                    connmap.put(extractKeys(mc), mc);
+                }
+                if (!poly_pressure) {
+                    ModelConnectionBlock mc = new ModelConnectionBlock();
+                    mc.setDestination(mod_cc_1_connection.getDestination());
+                    mc.setScale(mod_cc_1_connection.getScale());
+                    ModelSource[] src_list = mod_cc_1_connection.getSources();
+                    ModelSource[] src_list_new = new ModelSource[src_list.length];
+                    for (int i = 0; i < src_list_new.length; i++)
+                        src_list_new[i] = src_list[i];
+                    src_list_new[mod_cc_1_connection_src_ix] = new ModelSource(
+                            new ModelIdentifier("midi", "poly_pressure"));
+                    mc.setSources(src_list_new);
+                    connmap.put(extractKeys(mc), mc);
+                }
+            }
+
+            // Enable Vibration Sound Controllers : 76, 77, 78
+            ModelConnectionBlock found_vib_connection = null;
+            for (ModelConnectionBlock connection : performer_connections) {
+                ModelSource[] sources = connection.getSources();
+                if (sources.length != 0
+                        && sources[0].getIdentifier().getObject().equals("lfo")) {
+                    if (connection.getDestination().getIdentifier().equals(
+                            ModelDestination.DESTINATION_PITCH)) {
+                        if (found_vib_connection == null)
+                            found_vib_connection = connection;
+                        else {
+                            if (found_vib_connection.getSources().length > sources.length)
+                                found_vib_connection = connection;
+                            else if (found_vib_connection.getSources()[0]
+                                    .getIdentifier().getInstance() < 1) {
+                                if (found_vib_connection.getSources()[0]
+                                        .getIdentifier().getInstance() >
+                                        sources[0].getIdentifier().getInstance()) {
+                                    found_vib_connection = connection;
+                                }
+                            }
+                        }
+
+                    }
+                }
+            }
+
+            int instance = 1;
+
+            if (found_vib_connection != null) {
+                instance = found_vib_connection.getSources()[0].getIdentifier()
+                        .getInstance();
+            }
+            ModelConnectionBlock connection;
+
+            connection = new ModelConnectionBlock(
+                new ModelSource(new ModelIdentifier("midi_cc", "78"),
+                    ModelStandardTransform.DIRECTION_MIN2MAX,
+                    ModelStandardTransform.POLARITY_BIPOLAR,
+                    ModelStandardTransform.TRANSFORM_LINEAR),
+                2000, new ModelDestination(
+                    new ModelIdentifier("lfo", "delay2", instance)));
+            connmap.put(extractKeys(connection), connection);
+
+            final double scale = found_vib_connection == null ? 0
+                    : found_vib_connection.getScale();
+            connection = new ModelConnectionBlock(
+                new ModelSource(new ModelIdentifier("lfo", instance)),
+                new ModelSource(new ModelIdentifier("midi_cc", "77"),
+                    new ModelTransform() {
+                        double s = scale;
+                        public double transform(double value) {
+                            value = value * 2 - 1;
+                            value *= 600;
+                            if (s == 0) {
+                                return value;
+                            } else if (s > 0) {
+                                if (value < -s)
+                                    value = -s;
+                                return value;
+                            } else {
+                                if (value < s)
+                                    value = -s;
+                                return -value;
+                            }
+                        }
+                    }), new ModelDestination(ModelDestination.DESTINATION_PITCH));
+            connmap.put(extractKeys(connection), connection);
+
+            connection = new ModelConnectionBlock(
+                new ModelSource(new ModelIdentifier("midi_cc", "76"),
+                    ModelStandardTransform.DIRECTION_MIN2MAX,
+                    ModelStandardTransform.POLARITY_BIPOLAR,
+                    ModelStandardTransform.TRANSFORM_LINEAR),
+                2400, new ModelDestination(
+                    new ModelIdentifier("lfo", "freq", instance)));
+            connmap.put(extractKeys(connection), connection);
+
+        }
+
+        // Add default connection blocks
+        if (performer.isDefaultConnectionsEnabled())
+            for (ModelConnectionBlock connection : defaultconnections)
+                connmap.put(extractKeys(connection), connection);
+        // Add connection blocks from modelperformer
+        for (ModelConnectionBlock connection : performer_connections)
+            connmap.put(extractKeys(connection), connection);
+        // seperate connection blocks : Init time, Midi Time, Midi/Control Time,
+        // Control Time
+        List<ModelConnectionBlock> connections = new ArrayList<ModelConnectionBlock>();
+
+        midi_ctrl_connections = new int[128][];
+        for (int i = 0; i < midi_ctrl_connections.length; i++) {
+            midi_ctrl_connections[i] = null;
+        }
+        midi_connections = new int[5][];
+        for (int i = 0; i < midi_connections.length; i++) {
+            midi_connections[i] = null;
+        }
+
+        int ix = 0;
+        boolean mustBeOnTop = false;
+
+        for (ModelConnectionBlock connection : connmap.values()) {
+            if (connection.getDestination() != null) {
+                ModelDestination dest = connection.getDestination();
+                ModelIdentifier id = dest.getIdentifier();
+                if (id.getObject().equals("noteon")) {
+                    mustBeOnTop = true;
+                    if (id.getVariable().equals("keynumber"))
+                        forcedKeynumber = true;
+                    if (id.getVariable().equals("velocity"))
+                        forcedVelocity = true;
+                }
+            }
+            if (mustBeOnTop) {
+                connections.add(0, connection);
+                mustBeOnTop = false;
+            } else
+                connections.add(connection);
+        }
+
+        for (ModelConnectionBlock connection : connections) {
+            if (connection.getSources() != null) {
+                ModelSource[] srcs = connection.getSources();
+                for (int i = 0; i < srcs.length; i++) {
+                    processSource(srcs[i], ix);
+                }
+            }
+            ix++;
+        }
+
+        this.connections = new ModelConnectionBlock[connections.size()];
+        connections.toArray(this.connections);
+
+        this.ctrl_connections = new int[ctrl_connections_list.size()];
+
+        for (int i = 0; i < this.ctrl_connections.length; i++)
+            this.ctrl_connections[i] = ctrl_connections_list.get(i);
+
+        oscillators = new ModelOscillator[performer.getOscillators().size()];
+        performer.getOscillators().toArray(oscillators);
+
+        for (ModelConnectionBlock conn : connections) {
+            if (conn.getDestination() != null) {
+                if (isUnnecessaryTransform(conn.getDestination().getTransform())) {
+                    conn.getDestination().setTransform(null);
+                }
+            }
+            if (conn.getSources() != null) {
+                for (ModelSource src : conn.getSources()) {
+                    if (isUnnecessaryTransform(src.getTransform())) {
+                        src.setTransform(null);
+                    }
+                }
+            }
+        }
+
+    }
+
+    private static boolean isUnnecessaryTransform(ModelTransform transform) {
+        if (transform == null)
+            return false;
+        if (!(transform instanceof ModelStandardTransform))
+            return false;
+        ModelStandardTransform stransform = (ModelStandardTransform)transform;
+        if (stransform.getDirection() != ModelStandardTransform.DIRECTION_MIN2MAX)
+            return false;
+        if (stransform.getPolarity() != ModelStandardTransform.POLARITY_UNIPOLAR)
+            return false;
+        if (stransform.getTransform() != ModelStandardTransform.TRANSFORM_LINEAR)
+            return false;
+        return false;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftPointResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftPointResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,63 +1,63 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * A resampler that uses 0-order (nearest-neighbor) interpolation.
- *
- * @author Karl Helgason
- */
-public class SoftPointResampler extends SoftAbstractResampler {
-
-    public int getPadding() {
-        return 100;
-    }
-
-    public void interpolate(float[] in, float[] in_offset, float in_end,
-            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
-            int out_end) {
-        float pitch = startpitch[0];
-        float ix = in_offset[0];
-        int ox = out_offset[0];
-        float ix_end = in_end;
-        float ox_end = out_end;
-        if (pitchstep == 0) {
-            while (ix < ix_end && ox < ox_end) {
-                out[ox++] = in[(int) ix];
-                ix += pitch;
-            }
-        } else {
-            while (ix < ix_end && ox < ox_end) {
-                out[ox++] = in[(int) ix];
-                ix += pitch;
-                pitch += pitchstep;
-            }
-        }
-        in_offset[0] = ix;
-        out_offset[0] = ox;
-        startpitch[0] = pitch;
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * A resampler that uses 0-order (nearest-neighbor) interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftPointResampler extends SoftAbstractResampler {
+
+    public int getPadding() {
+        return 100;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        float ox_end = out_end;
+        if (pitchstep == 0) {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = in[(int) ix];
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                out[ox++] = in[(int) ix];
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftProcess.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftProcess.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,41 +1,41 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Control signal processor interface
- *
- * @author Karl Helgason
- */
-public interface SoftProcess extends SoftControl {
-
-    public void init(SoftSynthesizer synth);
-
-    public double[] get(int instance, String name);
-
-    public void processControlLogic();
-
-    public void reset();
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Control signal processor interface
+ *
+ * @author Karl Helgason
+ */
+public interface SoftProcess extends SoftControl {
+
+    public void init(SoftSynthesizer synth);
+
+    public double[] get(int instance, String name);
+
+    public void processControlLogic();
+
+    public void reset();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftProvider.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftProvider.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,51 +1,51 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.MidiDevice;
-import javax.sound.midi.MidiDevice.Info;
-import javax.sound.midi.spi.MidiDeviceProvider;
-
-/**
- * Software synthesizer provider class.
- *
- * @author Karl Helgason
- */
-public class SoftProvider extends MidiDeviceProvider {
-
-    protected static Info softinfo = SoftSynthesizer.info;
-    private static Info[] softinfos = {softinfo};
-
-    public MidiDevice.Info[] getDeviceInfo() {
-        return softinfos;
-    }
-
-    public MidiDevice getDevice(MidiDevice.Info info) {
-        if (info == softinfo) {
-            return new SoftSynthesizer();
-        }
-        return null;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiDevice.Info;
+import javax.sound.midi.spi.MidiDeviceProvider;
+
+/**
+ * Software synthesizer provider class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftProvider extends MidiDeviceProvider {
+
+    protected static Info softinfo = SoftSynthesizer.info;
+    private static Info[] softinfos = {softinfo};
+
+    public MidiDevice.Info[] getDeviceInfo() {
+        return softinfos;
+    }
+
+    public MidiDevice getDevice(MidiDevice.Info info) {
+        if (info == softinfo) {
+            return new SoftSynthesizer();
+        }
+        return null;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftReceiver.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,83 +1,83 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.TreeMap;
-
-import javax.sound.midi.MidiMessage;
-import javax.sound.midi.Receiver;
-import javax.sound.midi.ShortMessage;
-
-/**
- * Software synthesizer MIDI receiver class.
- *
- * @author Karl Helgason
- */
-public class SoftReceiver implements Receiver {
-
-    protected boolean open = true;
-    private Object control_mutex;
-    private SoftSynthesizer synth;
-    protected TreeMap<Long, Object> midimessages;
-    protected SoftMainMixer mainmixer;
-
-    public SoftReceiver(SoftSynthesizer synth) {
-        this.control_mutex = synth.control_mutex;
-        this.synth = synth;
-        this.mainmixer = synth.getMainMixer();
-        if (mainmixer != null)
-            this.midimessages = mainmixer.midimessages;
-    }
-
-    public void send(MidiMessage message, long timeStamp) {
-
-        synchronized (control_mutex) {
-            if (!open)
-                throw new IllegalStateException("Receiver is not open");
-        }
-
-        if (timeStamp != -1) {
-            synchronized (control_mutex) {
-                while (midimessages.get(timeStamp) != null)
-                    timeStamp++;
-                if (message instanceof ShortMessage
-                        && (((ShortMessage)message).getChannel() > 0xF)) {
-                    midimessages.put(timeStamp, message.clone());
-                } else {
-                    midimessages.put(timeStamp, message.getMessage());
-                }
-            }
-        } else {
-            mainmixer.processMessage(message);
-        }
-    }
-
-    public void close() {
-        synchronized (control_mutex) {
-            open = false;
-        }
-        synth.removeReceiver(this);
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.TreeMap;
+
+import javax.sound.midi.MidiMessage;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.ShortMessage;
+
+/**
+ * Software synthesizer MIDI receiver class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftReceiver implements Receiver {
+
+    protected boolean open = true;
+    private Object control_mutex;
+    private SoftSynthesizer synth;
+    protected TreeMap<Long, Object> midimessages;
+    protected SoftMainMixer mainmixer;
+
+    public SoftReceiver(SoftSynthesizer synth) {
+        this.control_mutex = synth.control_mutex;
+        this.synth = synth;
+        this.mainmixer = synth.getMainMixer();
+        if (mainmixer != null)
+            this.midimessages = mainmixer.midimessages;
+    }
+
+    public void send(MidiMessage message, long timeStamp) {
+
+        synchronized (control_mutex) {
+            if (!open)
+                throw new IllegalStateException("Receiver is not open");
+        }
+
+        if (timeStamp != -1) {
+            synchronized (control_mutex) {
+                while (midimessages.get(timeStamp) != null)
+                    timeStamp++;
+                if (message instanceof ShortMessage
+                        && (((ShortMessage)message).getChannel() > 0xF)) {
+                    midimessages.put(timeStamp, message.clone());
+                } else {
+                    midimessages.put(timeStamp, message.getMessage());
+                }
+            }
+        } else {
+            mainmixer.processMessage(message);
+        }
+    }
+
+    public void close() {
+        synchronized (control_mutex) {
+            open = false;
+        }
+        synth.removeReceiver(this);
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,35 +1,35 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Basic resampler interface.
- *
- * @author Karl Helgason
- */
-public interface SoftResampler {
-
-    public SoftResamplerStreamer openStreamer();
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Basic resampler interface.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftResampler {
+
+    public SoftResamplerStreamer openStreamer();
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftResamplerStreamer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftResamplerStreamer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,38 +1,38 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-
-/**
- * Resampler stream interface.
- *
- * @author Karl Helgason
- */
-public interface SoftResamplerStreamer extends ModelOscillatorStream {
-
-    public void open(ModelWavetable osc, float outputsamplerate)
-            throws IOException;
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+
+/**
+ * Resampler stream interface.
+ *
+ * @author Karl Helgason
+ */
+public interface SoftResamplerStreamer extends ModelOscillatorStream {
+
+    public void open(ModelWavetable osc, float outputsamplerate)
+            throws IOException;
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftReverb.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftReverb.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,465 +1,465 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.util.Arrays;
-
-/**
- * Reverb effect based on allpass/comb filters. First audio is send to 8
- * parelled comb filters and then mixed together and then finally send thru 3
- * different allpass filters.
- *
- * @author Karl Helgason
- */
-public class SoftReverb implements SoftAudioProcessor {
-
-    private class Delay {
-
-        private float[] delaybuffer;
-        private int rovepos = 0;
-
-        public Delay() {
-            delaybuffer = null;
-        }
-
-        public void setDelay(int delay) {
-            if (delay == 0)
-                delaybuffer = null;
-            else
-                delaybuffer = new float[delay];
-            rovepos = 0;
-        }
-
-        public void processReplace(float[] in, float[] out) {
-            float[] delaybuffer = this.delaybuffer;
-            if (delaybuffer == null)
-                return;
-            int len = in.length;
-            int rnlen = delaybuffer.length;
-            int rovepos = this.rovepos;
-
-            for (int i = 0; i < len; i++) {
-                float x = in[i];
-                out[i] = delaybuffer[rovepos];
-                delaybuffer[rovepos] = x;
-                rovepos = rovepos + 1;
-                if (rovepos == rnlen)
-                    rovepos = 0;
-                //rovepos = (rovepos + 1) % rnlen;
-            }
-            this.rovepos = rovepos;
-        }
-    }
-
-    private class AllPass {
-
-        private float[] delaybuffer;
-        private int delaybuffersize;
-        private int rovepos = 0;
-        private float feedback;
-
-        public AllPass(int size) {
-            delaybuffer = new float[size];
-            delaybuffersize = size;
-        }
-
-        public void setFeedBack(float feedback) {
-            this.feedback = feedback;
-        }
-        int ucount = 0;
-
-        public void processReplace(float in[], float out[]) {
-            int len = in.length;
-            for (int i = 0; i < len; i++) {
-
-                float delayout = delaybuffer[rovepos];
-
-                // undenormalise(delayout)
-                /*
-                if (((delayout > 0.0) && (delayout < 1.0E-10))
-                        || ((delayout < 0.0) && (delayout > -1.0E-10)))
-                    delayout = 0;
-                */
-
-                float input = in[i];
-                out[i] = -input + delayout;
-                delaybuffer[rovepos] = input + delayout * feedback;
-                if (++rovepos == delaybuffersize)
-                    rovepos = 0;
-            }
-
-            ucount++;
-            if (ucount == 10) {
-                ucount = 0;
-                for (int i = 0; i < delaybuffer.length; i++) {
-                    double v = delaybuffer[i];
-                    if (((v > 0.0) && (v < 1.0E-10))
-                            || ((v < 0.0) && (v > -1.0E-10))) {
-                        delaybuffer[i] = 0;
-                    }
-                }
-            }
-
-        }
-    }
-
-    private class Comb {
-
-        private float[] delaybuffer;
-        private int delaybuffersize;
-        private int rovepos = 0;
-        private float feedback;
-        private float filtertemp = 0;
-        private float filtercoeff1 = 0;
-        private float filtercoeff2 = 1;
-
-        public Comb(int size) {
-            delaybuffer = new float[size];
-            delaybuffersize = size;
-        }
-
-        public void setFeedBack(float feedback) {
-            this.feedback = feedback;
-        }
-        int ucount = 0;
-
-        public void processMix(float in[], float out[]) {
-            int len = in.length;
-
-            float filtercoeff2 = this.filtercoeff2 * feedback;
-
-            for (int i = 0; i < len; i++) {
-                float delayout = delaybuffer[rovepos];
-
-                // One Pole Lowpass Filter
-                filtertemp = (delayout * filtercoeff2)
-                        + (filtertemp * filtercoeff1);
-
-                // undenormalise(filtertemp)
-                /*
-                if (((filtertemp > 0.0) && (filtertemp < 1.0E-10))
-                        || ((filtertemp < 0.0) && (filtertemp > -1.0E-10)))
-                    filtertemp = 0;
-                */
-                out[i] += delayout;
-                delaybuffer[rovepos] = in[i] + (filtertemp);// * feedback);
-
-                if (++rovepos == delaybuffersize)
-                    rovepos = 0;
-
-            }
-            ucount++;
-            if (ucount == 10) {
-                ucount = 0;
-                if (((filtertemp > 0.0) && (filtertemp < 1.0E-10))
-                        || ((filtertemp < 0.0) && (filtertemp > -1.0E-10))) {
-                    filtertemp = 0;
-                }
-                for (int i = 0; i < delaybuffer.length; i++) {
-                    double v = delaybuffer[i];
-                    if (((v > 0.0) && (v < 1.0E-10))
-                            || ((v < 0.0) && (v > -1.0E-10))) {
-                        delaybuffer[i] = 0;
-                    }
-                }
-            }
-
-
-        }
-
-        public void setDamp(float val) {
-            filtercoeff1 = val;
-            filtercoeff2 = 1 - filtercoeff1;
-        }
-    }
-    private float roomsize;
-    private float damp;
-    private float gain = 1;
-    private Delay delay;
-    private Comb[] combL;
-    private Comb[] combR;
-    private AllPass[] allpassL;
-    private AllPass[] allpassR;
-    private float[] input;
-    private float[] outR;
-    private float[] outL;
-    private boolean mix = true;
-    private SoftAudioBuffer inputA;
-    private SoftAudioBuffer left;
-    private SoftAudioBuffer right;
-    private SoftSynthesizer synth;
-    private boolean dirty = true;
-    private float dirty_roomsize;
-    private float dirty_damp;
-    private float dirty_predelay;
-    private float dirty_gain;
-
-    public void init(SoftSynthesizer synth) {
-        this.synth = synth;
-        double samplerate = synth.getFormat().getSampleRate();
-
-        double freqscale = ((double) samplerate) / 44100.0;
-        // freqscale = 1.0/ freqscale;
-
-        int stereospread = 23;
-
-        delay = new Delay();
-
-        combL = new Comb[8];
-        combR = new Comb[8];
-        combL[0] = new Comb((int) (freqscale * (1116)));
-        combR[0] = new Comb((int) (freqscale * (1116 + stereospread)));
-        combL[1] = new Comb((int) (freqscale * (1188)));
-        combR[1] = new Comb((int) (freqscale * (1188 + stereospread)));
-        combL[2] = new Comb((int) (freqscale * (1277)));
-        combR[2] = new Comb((int) (freqscale * (1277 + stereospread)));
-        combL[3] = new Comb((int) (freqscale * (1356)));
-        combR[3] = new Comb((int) (freqscale * (1356 + stereospread)));
-        combL[4] = new Comb((int) (freqscale * (1422)));
-        combR[4] = new Comb((int) (freqscale * (1422 + stereospread)));
-        combL[5] = new Comb((int) (freqscale * (1491)));
-        combR[5] = new Comb((int) (freqscale * (1491 + stereospread)));
-        combL[6] = new Comb((int) (freqscale * (1557)));
-        combR[6] = new Comb((int) (freqscale * (1557 + stereospread)));
-        combL[7] = new Comb((int) (freqscale * (1617)));
-        combR[7] = new Comb((int) (freqscale * (1617 + stereospread)));
-
-        allpassL = new AllPass[4];
-        allpassR = new AllPass[4];
-        allpassL[0] = new AllPass((int) (freqscale * (556)));
-        allpassR[0] = new AllPass((int) (freqscale * (556 + stereospread)));
-        allpassL[1] = new AllPass((int) (freqscale * (441)));
-        allpassR[1] = new AllPass((int) (freqscale * (441 + stereospread)));
-        allpassL[2] = new AllPass((int) (freqscale * (341)));
-        allpassR[2] = new AllPass((int) (freqscale * (341 + stereospread)));
-        allpassL[3] = new AllPass((int) (freqscale * (225)));
-        allpassR[3] = new AllPass((int) (freqscale * (225 + stereospread)));
-
-        for (int i = 0; i < allpassL.length; i++) {
-            allpassL[i].setFeedBack(0.5f);
-            allpassR[i].setFeedBack(0.5f);
-        }
-
-        /* Init other settings */
-        globalParameterControlChange(new int[]{0x01 * 128 + 0x01}, 0, 4);
-
-    }
-
-    public void setInput(int pin, SoftAudioBuffer input) {
-        if (pin == 0)
-            inputA = input;
-    }
-
-    public void setOutput(int pin, SoftAudioBuffer output) {
-        if (pin == 0)
-            left = output;
-        if (pin == 1)
-            right = output;
-    }
-
-    public void setMixMode(boolean mix) {
-        this.mix = mix;
-    }
-    private double silentcounter = 1000;
-
-    public void processAudio() {
-        if (this.inputA.isSilent()) {
-            silentcounter += 1 / synth.getControlRate();
-
-            if (silentcounter > 60) {
-                if (!mix) {
-                    left.clear();
-                    right.clear();
-                }
-                return;
-            }
-        } else
-            silentcounter = 0;
-
-        float[] inputA = this.inputA.array();
-        float[] left = this.left.array();
-        float[] right = this.right == null ? null : this.right.array();
-
-        int numsamples = inputA.length;
-        if (input == null || input.length < numsamples)
-            input = new float[numsamples];
-
-        float again = gain * 0.018f / 2;
-
-        for (int i = 0; i < numsamples; i++)
-            input[i] = inputA[i] * again;
-
-        delay.processReplace(input, input);
-
-
-        if (right != null) {
-            if (outR == null || outR.length < numsamples)
-                outR = new float[numsamples];
-            Arrays.fill(outR, 0);
-            for (int i = 0; i < combR.length; i++)
-                combR[i].processMix(input, outR);
-            for (int i = 0; i < allpassL.length; i++)
-                allpassR[i].processReplace(outR, outR);
-
-            if (mix) {
-                for (int i = 0; i < numsamples; i++)
-                    right[i] += outR[i];
-            } else {
-                for (int i = 0; i < numsamples; i++)
-                    right[i] = outR[i];
-            }
-        }
-
-
-        if (outL == null || outL.length < numsamples)
-            outL = new float[numsamples];
-        Arrays.fill(outL, 0);
-        for (int i = 0; i < combL.length; i++)
-            combL[i].processMix(input, outL);
-        for (int i = 0; i < allpassL.length; i++)
-            allpassL[i].processReplace(outL, outL);
-
-        if (mix) {
-            for (int i = 0; i < numsamples; i++)
-                left[i] += outL[i];
-        } else {
-            for (int i = 0; i < numsamples; i++)
-                left[i] = outL[i];
-        }
-
-
-    }
-
-    public void globalParameterControlChange(int[] slothpath, long param,
-            long value) {
-        if (slothpath.length == 1) {
-            if (slothpath[0] == 0x01 * 128 + 0x01) {
-
-                if (param == 0) {
-                    if (value == 0) {
-                        // Small Room A small size room with a length
-                        // of 5m or so.
-                        dirty_roomsize = (1.1f);
-                        dirty_damp = (5000);
-                        dirty_predelay = (0);
-                        dirty_gain = (4);
-                        dirty = true;
-                    }
-                    if (value == 1) {
-                        // Medium Room A medium size room with a length
-                        // of 10m or so.
-                        dirty_roomsize = (1.3f);
-                        dirty_damp = (5000);
-                        dirty_predelay = (0);
-                        dirty_gain = (3);
-                        dirty = true;
-                    }
-                    if (value == 2) {
-                        // Large Room A large size room suitable for
-                        // live performances.
-                        dirty_roomsize = (1.5f);
-                        dirty_damp = (5000);
-                        dirty_predelay = (0);
-                        dirty_gain = (2);
-                        dirty = true;
-                    }
-                    if (value == 3) {
-                        // Medium Hall A medium size concert hall.
-                        dirty_roomsize = (1.8f);
-                        dirty_damp = (24000);
-                        dirty_predelay = (0.02f);
-                        dirty_gain = (1.5f);
-                        dirty = true;
-                    }
-                    if (value == 4) {
-                        // Large Hall A large size concert hall
-                        // suitable for a full orchestra.
-                        dirty_roomsize = (1.8f);
-                        dirty_damp = (24000);
-                        dirty_predelay = (0.03f);
-                        dirty_gain = (1.5f);
-                        dirty = true;
-                    }
-                    if (value == 8) {
-                        // Plate A plate reverb simulation.
-                        dirty_roomsize = (1.3f);
-                        dirty_damp = (2500);
-                        dirty_predelay = (0);
-                        dirty_gain = (6);
-                        dirty = true;
-                    }
-                } else if (param == 1) {
-                    dirty_roomsize = ((float) (Math.exp((value - 40) * 0.025)));
-                    dirty = true;
-                }
-
-            }
-        }
-    }
-
-    public void processControlLogic() {
-        if (dirty) {
-            dirty = false;
-            setRoomSize(dirty_roomsize);
-            setDamp(dirty_damp);
-            setPreDelay(dirty_predelay);
-            setGain(dirty_gain);
-        }
-    }
-
-    public void setRoomSize(float value) {
-        roomsize = 1 - (0.17f / value);
-
-        for (int i = 0; i < 8; i++) {
-            combL[i].feedback = roomsize;
-            combR[i].feedback = roomsize;
-        }
-    }
-
-    public void setPreDelay(float value) {
-        delay.setDelay((int)(value * synth.getFormat().getSampleRate()));
-    }
-
-    public void setGain(float gain) {
-        this.gain = gain;
-    }
-
-    public void setDamp(float value) {
-        double x = (value / synth.getFormat().getSampleRate()) * (2 * Math.PI);
-        double cx = 2 - Math.cos(x);
-        damp = (float)(cx - Math.sqrt(cx * cx - 1));
-        if (damp > 1)
-            damp = 1;
-        if (damp < 0)
-            damp = 0;
-
-        // damp = value * 0.4f;
-        for (int i = 0; i < 8; i++) {
-            combL[i].setDamp(damp);
-            combR[i].setDamp(damp);
-        }
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.util.Arrays;
+
+/**
+ * Reverb effect based on allpass/comb filters. First audio is send to 8
+ * parelled comb filters and then mixed together and then finally send thru 3
+ * different allpass filters.
+ *
+ * @author Karl Helgason
+ */
+public class SoftReverb implements SoftAudioProcessor {
+
+    private class Delay {
+
+        private float[] delaybuffer;
+        private int rovepos = 0;
+
+        public Delay() {
+            delaybuffer = null;
+        }
+
+        public void setDelay(int delay) {
+            if (delay == 0)
+                delaybuffer = null;
+            else
+                delaybuffer = new float[delay];
+            rovepos = 0;
+        }
+
+        public void processReplace(float[] in, float[] out) {
+            float[] delaybuffer = this.delaybuffer;
+            if (delaybuffer == null)
+                return;
+            int len = in.length;
+            int rnlen = delaybuffer.length;
+            int rovepos = this.rovepos;
+
+            for (int i = 0; i < len; i++) {
+                float x = in[i];
+                out[i] = delaybuffer[rovepos];
+                delaybuffer[rovepos] = x;
+                rovepos = rovepos + 1;
+                if (rovepos == rnlen)
+                    rovepos = 0;
+                //rovepos = (rovepos + 1) % rnlen;
+            }
+            this.rovepos = rovepos;
+        }
+    }
+
+    private class AllPass {
+
+        private float[] delaybuffer;
+        private int delaybuffersize;
+        private int rovepos = 0;
+        private float feedback;
+
+        public AllPass(int size) {
+            delaybuffer = new float[size];
+            delaybuffersize = size;
+        }
+
+        public void setFeedBack(float feedback) {
+            this.feedback = feedback;
+        }
+        int ucount = 0;
+
+        public void processReplace(float in[], float out[]) {
+            int len = in.length;
+            for (int i = 0; i < len; i++) {
+
+                float delayout = delaybuffer[rovepos];
+
+                // undenormalise(delayout)
+                /*
+                if (((delayout > 0.0) && (delayout < 1.0E-10))
+                        || ((delayout < 0.0) && (delayout > -1.0E-10)))
+                    delayout = 0;
+                */
+
+                float input = in[i];
+                out[i] = -input + delayout;
+                delaybuffer[rovepos] = input + delayout * feedback;
+                if (++rovepos == delaybuffersize)
+                    rovepos = 0;
+            }
+
+            ucount++;
+            if (ucount == 10) {
+                ucount = 0;
+                for (int i = 0; i < delaybuffer.length; i++) {
+                    double v = delaybuffer[i];
+                    if (((v > 0.0) && (v < 1.0E-10))
+                            || ((v < 0.0) && (v > -1.0E-10))) {
+                        delaybuffer[i] = 0;
+                    }
+                }
+            }
+
+        }
+    }
+
+    private class Comb {
+
+        private float[] delaybuffer;
+        private int delaybuffersize;
+        private int rovepos = 0;
+        private float feedback;
+        private float filtertemp = 0;
+        private float filtercoeff1 = 0;
+        private float filtercoeff2 = 1;
+
+        public Comb(int size) {
+            delaybuffer = new float[size];
+            delaybuffersize = size;
+        }
+
+        public void setFeedBack(float feedback) {
+            this.feedback = feedback;
+        }
+        int ucount = 0;
+
+        public void processMix(float in[], float out[]) {
+            int len = in.length;
+
+            float filtercoeff2 = this.filtercoeff2 * feedback;
+
+            for (int i = 0; i < len; i++) {
+                float delayout = delaybuffer[rovepos];
+
+                // One Pole Lowpass Filter
+                filtertemp = (delayout * filtercoeff2)
+                        + (filtertemp * filtercoeff1);
+
+                // undenormalise(filtertemp)
+                /*
+                if (((filtertemp > 0.0) && (filtertemp < 1.0E-10))
+                        || ((filtertemp < 0.0) && (filtertemp > -1.0E-10)))
+                    filtertemp = 0;
+                */
+                out[i] += delayout;
+                delaybuffer[rovepos] = in[i] + (filtertemp);// * feedback);
+
+                if (++rovepos == delaybuffersize)
+                    rovepos = 0;
+
+            }
+            ucount++;
+            if (ucount == 10) {
+                ucount = 0;
+                if (((filtertemp > 0.0) && (filtertemp < 1.0E-10))
+                        || ((filtertemp < 0.0) && (filtertemp > -1.0E-10))) {
+                    filtertemp = 0;
+                }
+                for (int i = 0; i < delaybuffer.length; i++) {
+                    double v = delaybuffer[i];
+                    if (((v > 0.0) && (v < 1.0E-10))
+                            || ((v < 0.0) && (v > -1.0E-10))) {
+                        delaybuffer[i] = 0;
+                    }
+                }
+            }
+
+
+        }
+
+        public void setDamp(float val) {
+            filtercoeff1 = val;
+            filtercoeff2 = 1 - filtercoeff1;
+        }
+    }
+    private float roomsize;
+    private float damp;
+    private float gain = 1;
+    private Delay delay;
+    private Comb[] combL;
+    private Comb[] combR;
+    private AllPass[] allpassL;
+    private AllPass[] allpassR;
+    private float[] input;
+    private float[] outR;
+    private float[] outL;
+    private boolean mix = true;
+    private SoftAudioBuffer inputA;
+    private SoftAudioBuffer left;
+    private SoftAudioBuffer right;
+    private SoftSynthesizer synth;
+    private boolean dirty = true;
+    private float dirty_roomsize;
+    private float dirty_damp;
+    private float dirty_predelay;
+    private float dirty_gain;
+
+    public void init(SoftSynthesizer synth) {
+        this.synth = synth;
+        double samplerate = synth.getFormat().getSampleRate();
+
+        double freqscale = ((double) samplerate) / 44100.0;
+        // freqscale = 1.0/ freqscale;
+
+        int stereospread = 23;
+
+        delay = new Delay();
+
+        combL = new Comb[8];
+        combR = new Comb[8];
+        combL[0] = new Comb((int) (freqscale * (1116)));
+        combR[0] = new Comb((int) (freqscale * (1116 + stereospread)));
+        combL[1] = new Comb((int) (freqscale * (1188)));
+        combR[1] = new Comb((int) (freqscale * (1188 + stereospread)));
+        combL[2] = new Comb((int) (freqscale * (1277)));
+        combR[2] = new Comb((int) (freqscale * (1277 + stereospread)));
+        combL[3] = new Comb((int) (freqscale * (1356)));
+        combR[3] = new Comb((int) (freqscale * (1356 + stereospread)));
+        combL[4] = new Comb((int) (freqscale * (1422)));
+        combR[4] = new Comb((int) (freqscale * (1422 + stereospread)));
+        combL[5] = new Comb((int) (freqscale * (1491)));
+        combR[5] = new Comb((int) (freqscale * (1491 + stereospread)));
+        combL[6] = new Comb((int) (freqscale * (1557)));
+        combR[6] = new Comb((int) (freqscale * (1557 + stereospread)));
+        combL[7] = new Comb((int) (freqscale * (1617)));
+        combR[7] = new Comb((int) (freqscale * (1617 + stereospread)));
+
+        allpassL = new AllPass[4];
+        allpassR = new AllPass[4];
+        allpassL[0] = new AllPass((int) (freqscale * (556)));
+        allpassR[0] = new AllPass((int) (freqscale * (556 + stereospread)));
+        allpassL[1] = new AllPass((int) (freqscale * (441)));
+        allpassR[1] = new AllPass((int) (freqscale * (441 + stereospread)));
+        allpassL[2] = new AllPass((int) (freqscale * (341)));
+        allpassR[2] = new AllPass((int) (freqscale * (341 + stereospread)));
+        allpassL[3] = new AllPass((int) (freqscale * (225)));
+        allpassR[3] = new AllPass((int) (freqscale * (225 + stereospread)));
+
+        for (int i = 0; i < allpassL.length; i++) {
+            allpassL[i].setFeedBack(0.5f);
+            allpassR[i].setFeedBack(0.5f);
+        }
+
+        /* Init other settings */
+        globalParameterControlChange(new int[]{0x01 * 128 + 0x01}, 0, 4);
+
+    }
+
+    public void setInput(int pin, SoftAudioBuffer input) {
+        if (pin == 0)
+            inputA = input;
+    }
+
+    public void setOutput(int pin, SoftAudioBuffer output) {
+        if (pin == 0)
+            left = output;
+        if (pin == 1)
+            right = output;
+    }
+
+    public void setMixMode(boolean mix) {
+        this.mix = mix;
+    }
+    private double silentcounter = 1000;
+
+    public void processAudio() {
+        if (this.inputA.isSilent()) {
+            silentcounter += 1 / synth.getControlRate();
+
+            if (silentcounter > 60) {
+                if (!mix) {
+                    left.clear();
+                    right.clear();
+                }
+                return;
+            }
+        } else
+            silentcounter = 0;
+
+        float[] inputA = this.inputA.array();
+        float[] left = this.left.array();
+        float[] right = this.right == null ? null : this.right.array();
+
+        int numsamples = inputA.length;
+        if (input == null || input.length < numsamples)
+            input = new float[numsamples];
+
+        float again = gain * 0.018f / 2;
+
+        for (int i = 0; i < numsamples; i++)
+            input[i] = inputA[i] * again;
+
+        delay.processReplace(input, input);
+
+
+        if (right != null) {
+            if (outR == null || outR.length < numsamples)
+                outR = new float[numsamples];
+            Arrays.fill(outR, 0);
+            for (int i = 0; i < combR.length; i++)
+                combR[i].processMix(input, outR);
+            for (int i = 0; i < allpassL.length; i++)
+                allpassR[i].processReplace(outR, outR);
+
+            if (mix) {
+                for (int i = 0; i < numsamples; i++)
+                    right[i] += outR[i];
+            } else {
+                for (int i = 0; i < numsamples; i++)
+                    right[i] = outR[i];
+            }
+        }
+
+
+        if (outL == null || outL.length < numsamples)
+            outL = new float[numsamples];
+        Arrays.fill(outL, 0);
+        for (int i = 0; i < combL.length; i++)
+            combL[i].processMix(input, outL);
+        for (int i = 0; i < allpassL.length; i++)
+            allpassL[i].processReplace(outL, outL);
+
+        if (mix) {
+            for (int i = 0; i < numsamples; i++)
+                left[i] += outL[i];
+        } else {
+            for (int i = 0; i < numsamples; i++)
+                left[i] = outL[i];
+        }
+
+
+    }
+
+    public void globalParameterControlChange(int[] slothpath, long param,
+            long value) {
+        if (slothpath.length == 1) {
+            if (slothpath[0] == 0x01 * 128 + 0x01) {
+
+                if (param == 0) {
+                    if (value == 0) {
+                        // Small Room A small size room with a length
+                        // of 5m or so.
+                        dirty_roomsize = (1.1f);
+                        dirty_damp = (5000);
+                        dirty_predelay = (0);
+                        dirty_gain = (4);
+                        dirty = true;
+                    }
+                    if (value == 1) {
+                        // Medium Room A medium size room with a length
+                        // of 10m or so.
+                        dirty_roomsize = (1.3f);
+                        dirty_damp = (5000);
+                        dirty_predelay = (0);
+                        dirty_gain = (3);
+                        dirty = true;
+                    }
+                    if (value == 2) {
+                        // Large Room A large size room suitable for
+                        // live performances.
+                        dirty_roomsize = (1.5f);
+                        dirty_damp = (5000);
+                        dirty_predelay = (0);
+                        dirty_gain = (2);
+                        dirty = true;
+                    }
+                    if (value == 3) {
+                        // Medium Hall A medium size concert hall.
+                        dirty_roomsize = (1.8f);
+                        dirty_damp = (24000);
+                        dirty_predelay = (0.02f);
+                        dirty_gain = (1.5f);
+                        dirty = true;
+                    }
+                    if (value == 4) {
+                        // Large Hall A large size concert hall
+                        // suitable for a full orchestra.
+                        dirty_roomsize = (1.8f);
+                        dirty_damp = (24000);
+                        dirty_predelay = (0.03f);
+                        dirty_gain = (1.5f);
+                        dirty = true;
+                    }
+                    if (value == 8) {
+                        // Plate A plate reverb simulation.
+                        dirty_roomsize = (1.3f);
+                        dirty_damp = (2500);
+                        dirty_predelay = (0);
+                        dirty_gain = (6);
+                        dirty = true;
+                    }
+                } else if (param == 1) {
+                    dirty_roomsize = ((float) (Math.exp((value - 40) * 0.025)));
+                    dirty = true;
+                }
+
+            }
+        }
+    }
+
+    public void processControlLogic() {
+        if (dirty) {
+            dirty = false;
+            setRoomSize(dirty_roomsize);
+            setDamp(dirty_damp);
+            setPreDelay(dirty_predelay);
+            setGain(dirty_gain);
+        }
+    }
+
+    public void setRoomSize(float value) {
+        roomsize = 1 - (0.17f / value);
+
+        for (int i = 0; i < 8; i++) {
+            combL[i].feedback = roomsize;
+            combR[i].feedback = roomsize;
+        }
+    }
+
+    public void setPreDelay(float value) {
+        delay.setDelay((int)(value * synth.getFormat().getSampleRate()));
+    }
+
+    public void setGain(float gain) {
+        this.gain = gain;
+    }
+
+    public void setDamp(float value) {
+        double x = (value / synth.getFormat().getSampleRate()) * (2 * Math.PI);
+        double cx = 2 - Math.cos(x);
+        damp = (float)(cx - Math.sqrt(cx * cx - 1));
+        if (damp > 1)
+            damp = 1;
+        if (damp < 0)
+            damp = 0;
+
+        // damp = value * 0.4f;
+        for (int i = 0; i < 8; i++) {
+            combL[i].setDamp(damp);
+            combR[i].setDamp(damp);
+        }
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftShortMessage.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftShortMessage.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,58 +1,58 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import javax.sound.midi.InvalidMidiDataException;
-import javax.sound.midi.ShortMessage;
-
-/**
- * A short message class that support for than 16 midi channels.
- *
- * @author Karl Helgason
- */
-public class SoftShortMessage extends ShortMessage {
-
-    int channel = 0;
-
-    public int getChannel() {
-        return channel;
-    }
-
-    public void setMessage(int command, int channel, int data1, int data2)
-            throws InvalidMidiDataException {
-        this.channel = channel;
-        super.setMessage(command, channel & 0xF, data1, data2);
-    }
-
-    public Object clone() {
-        SoftShortMessage clone = new SoftShortMessage();
-        try {
-            clone.setMessage(getCommand(), getChannel(), getData1(), getData2());
-        } catch (InvalidMidiDataException e) {
-            throw new IllegalArgumentException(e);
-        }
-        return clone;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import javax.sound.midi.InvalidMidiDataException;
+import javax.sound.midi.ShortMessage;
+
+/**
+ * A short message class that support for than 16 midi channels.
+ *
+ * @author Karl Helgason
+ */
+public class SoftShortMessage extends ShortMessage {
+
+    int channel = 0;
+
+    public int getChannel() {
+        return channel;
+    }
+
+    public void setMessage(int command, int channel, int data1, int data2)
+            throws InvalidMidiDataException {
+        this.channel = channel;
+        super.setMessage(command, channel & 0xF, data1, data2);
+    }
+
+    public Object clone() {
+        SoftShortMessage clone = new SoftShortMessage();
+        try {
+            clone.setMessage(getCommand(), getChannel(), getData1(), getData2());
+        } catch (InvalidMidiDataException e) {
+            throw new IllegalArgumentException(e);
+        }
+        return clone;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftSincResampler.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftSincResampler.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,140 +1,140 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-/**
- * Hann windowed sinc interpolation resampler with anti-alias filtering.
- *
- * Using 30 points for the interpolation.
- *
- * @author Karl Helgason
- */
-public class SoftSincResampler extends SoftAbstractResampler {
-
-    double[] din;
-    float[][][] sinc_table;
-    int sinc_scale_size = 100;
-    int sinc_table_fsize = 800;
-    int sinc_table_size = 30;
-    int sinc_table_center = sinc_table_size / 2;
-
-    public SoftSincResampler() {
-        super();
-        sinc_table = new float[sinc_scale_size][sinc_table_fsize][];
-        for (int s = 0; s < sinc_scale_size; s++) {
-            float scale = (float) (1.0 / (1.0 + Math.pow(s, 1.1) / 10.0));
-            for (int i = 0; i < sinc_table_fsize; i++) {
-                sinc_table[s][i] = sincTable(sinc_table_size,
-                        -i / ((float)sinc_table_fsize), scale);
-            }
-        }
-    }
-
-    // Normalized sinc function
-    public static double sinc(double x) {
-        return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
-    }
-
-    // Generate hann window suitable for windowing sinc
-    public static float[] wHanning(int size, float offset) {
-        float[] window_table = new float[size];
-        for (int k = 0; k < size; k++) {
-            window_table[k] = (float)(-0.5
-                    * Math.cos(2.0 * Math.PI * (double)(k + offset)
-                        / (double) size) + 0.5);
-        }
-        return window_table;
-    }
-
-    // Generate sinc table
-    public static float[] sincTable(int size, float offset, float scale) {
-        int center = size / 2;
-        float[] w = wHanning(size, offset);
-        for (int k = 0; k < size; k++)
-            w[k] *= sinc((-center + k + offset) * scale) * scale;
-        return w;
-    }
-
-    public int getPadding() // must be at least half of sinc_table_size
-    {
-        return sinc_table_size / 2 + 2;
-    }
-
-    public void interpolate(float[] in, float[] in_offset, float in_end,
-            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
-            int out_end) {
-        float pitch = startpitch[0];
-        float ix = in_offset[0];
-        int ox = out_offset[0];
-        float ix_end = in_end;
-        int ox_end = out_end;
-        int max_p = sinc_scale_size - 1;
-        if (pitchstep == 0) {
-
-            int p = (int) ((pitch - 1) * 10.0f);
-            if (p < 0)
-                p = 0;
-            else if (p > max_p)
-                p = max_p;
-            float[][] sinc_table_f = this.sinc_table[p];
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                float[] sinc_table =
-                        sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
-                int xx = iix - sinc_table_center;
-                float y = 0;
-                for (int i = 0; i < sinc_table_size; i++, xx++)
-                    y += in[xx] * sinc_table[i];
-                out[ox++] = y;
-                ix += pitch;
-            }
-        } else {
-            while (ix < ix_end && ox < ox_end) {
-                int iix = (int) ix;
-                int p = (int) ((pitch - 1) * 10.0f);
-                if (p < 0)
-                    p = 0;
-                else if (p > max_p)
-                    p = max_p;
-                float[][] sinc_table_f = this.sinc_table[p];
-
-                float[] sinc_table =
-                        sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
-                int xx = iix - sinc_table_center;
-                float y = 0;
-                for (int i = 0; i < sinc_table_size; i++, xx++)
-                    y += in[xx] * sinc_table[i];
-                out[ox++] = y;
-
-                ix += pitch;
-                pitch += pitchstep;
-            }
-        }
-        in_offset[0] = ix;
-        out_offset[0] = ox;
-        startpitch[0] = pitch;
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+/**
+ * Hann windowed sinc interpolation resampler with anti-alias filtering.
+ *
+ * Using 30 points for the interpolation.
+ *
+ * @author Karl Helgason
+ */
+public class SoftSincResampler extends SoftAbstractResampler {
+
+    double[] din;
+    float[][][] sinc_table;
+    int sinc_scale_size = 100;
+    int sinc_table_fsize = 800;
+    int sinc_table_size = 30;
+    int sinc_table_center = sinc_table_size / 2;
+
+    public SoftSincResampler() {
+        super();
+        sinc_table = new float[sinc_scale_size][sinc_table_fsize][];
+        for (int s = 0; s < sinc_scale_size; s++) {
+            float scale = (float) (1.0 / (1.0 + Math.pow(s, 1.1) / 10.0));
+            for (int i = 0; i < sinc_table_fsize; i++) {
+                sinc_table[s][i] = sincTable(sinc_table_size,
+                        -i / ((float)sinc_table_fsize), scale);
+            }
+        }
+    }
+
+    // Normalized sinc function
+    public static double sinc(double x) {
+        return (x == 0.0) ? 1.0 : Math.sin(Math.PI * x) / (Math.PI * x);
+    }
+
+    // Generate hann window suitable for windowing sinc
+    public static float[] wHanning(int size, float offset) {
+        float[] window_table = new float[size];
+        for (int k = 0; k < size; k++) {
+            window_table[k] = (float)(-0.5
+                    * Math.cos(2.0 * Math.PI * (double)(k + offset)
+                        / (double) size) + 0.5);
+        }
+        return window_table;
+    }
+
+    // Generate sinc table
+    public static float[] sincTable(int size, float offset, float scale) {
+        int center = size / 2;
+        float[] w = wHanning(size, offset);
+        for (int k = 0; k < size; k++)
+            w[k] *= sinc((-center + k + offset) * scale) * scale;
+        return w;
+    }
+
+    public int getPadding() // must be at least half of sinc_table_size
+    {
+        return sinc_table_size / 2 + 2;
+    }
+
+    public void interpolate(float[] in, float[] in_offset, float in_end,
+            float[] startpitch, float pitchstep, float[] out, int[] out_offset,
+            int out_end) {
+        float pitch = startpitch[0];
+        float ix = in_offset[0];
+        int ox = out_offset[0];
+        float ix_end = in_end;
+        int ox_end = out_end;
+        int max_p = sinc_scale_size - 1;
+        if (pitchstep == 0) {
+
+            int p = (int) ((pitch - 1) * 10.0f);
+            if (p < 0)
+                p = 0;
+            else if (p > max_p)
+                p = max_p;
+            float[][] sinc_table_f = this.sinc_table[p];
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                float[] sinc_table =
+                        sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+                ix += pitch;
+            }
+        } else {
+            while (ix < ix_end && ox < ox_end) {
+                int iix = (int) ix;
+                int p = (int) ((pitch - 1) * 10.0f);
+                if (p < 0)
+                    p = 0;
+                else if (p > max_p)
+                    p = max_p;
+                float[][] sinc_table_f = this.sinc_table[p];
+
+                float[] sinc_table =
+                        sinc_table_f[(int)((ix - iix) * sinc_table_fsize)];
+                int xx = iix - sinc_table_center;
+                float y = 0;
+                for (int i = 0; i < sinc_table_size; i++, xx++)
+                    y += in[xx] * sinc_table[i];
+                out[ox++] = y;
+
+                ix += pitch;
+                pitch += pitchstep;
+            }
+        }
+        in_offset[0] = ix;
+        out_offset[0] = ox;
+        startpitch[0] = pitch;
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftSynthesizer.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,992 +1,992 @@
-/*
- * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package com.sun.media.sound;
-
-import java.io.File;
-import java.io.IOException;
-import java.security.AccessControlException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.sound.midi.Instrument;
-import javax.sound.midi.MidiChannel;
-import javax.sound.midi.MidiDevice;
-import javax.sound.midi.MidiSystem;
-import javax.sound.midi.MidiUnavailableException;
-import javax.sound.midi.Patch;
-import javax.sound.midi.Receiver;
-import javax.sound.midi.Soundbank;
-import javax.sound.midi.Transmitter;
-import javax.sound.midi.VoiceStatus;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.LineUnavailableException;
-import javax.sound.sampled.SourceDataLine;
-
-/**
- * The software synthesizer class.
- *
- * @author Karl Helgason
- */
-public class SoftSynthesizer implements AudioSynthesizer,
-        ReferenceCountingDevice {
-
-    private static class Info extends MidiDevice.Info {
-        public Info() {
-            super(INFO_NAME, INFO_VENDOR, INFO_DESCRIPTION, INFO_VERSION);
-        }
-    }
-
-    protected static final String INFO_NAME = "Gervill";
-    protected static final String INFO_VENDOR = "OpenJDK";
-    protected static final String INFO_DESCRIPTION = "Software MIDI Synthesizer";
-    protected static final String INFO_VERSION = "1.0";
-    protected static MidiDevice.Info info = new Info();
-
-    private static Soundbank defaultSoundBank = null;
-
-    protected Object control_mutex = this;
-
-    protected int voiceIDCounter = 0;
-
-    // 0: default
-    // 1: DLS Voice Allocation
-    protected int voice_allocation_mode = 0;
-
-    protected boolean reverb_on = true;
-    protected boolean chorus_on = true;
-    protected boolean agc_on = true;
-
-    protected SoftChannel[] channels;
-    protected SoftChannelProxy[] external_channels = null;
-
-    private boolean largemode = false;
-
-    // 0: GM Mode off (default)
-    // 1: GM Level 1
-    // 2: GM Level 2
-    private int gmmode = 0;
-
-    private int deviceid = 0;
-
-    private AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
-
-    private SourceDataLine sourceDataLine = null;
-
-    private SoftAudioPusher pusher = null;
-    private AudioInputStream pusher_stream = null;
-
-    private float controlrate = 147f;
-
-    private boolean open = false;
-    private boolean implicitOpen = false;
-
-    private SoftResampler resampler = new SoftLinearResampler();
-
-    private int number_of_midi_channels = 16;
-    private int maxpoly = 64;
-    private long latency = 200000; // 200 msec
-    private boolean jitter_correction = false;
-
-    private SoftMainMixer mainmixer;
-    private SoftVoice[] voices;
-
-    private Map<String, SoftTuning> tunings
-            = new HashMap<String, SoftTuning>();
-    private Map<String, SoftInstrument> inslist
-            = new HashMap<String, SoftInstrument>();
-    private Map<String, ModelInstrument> availlist
-            = new HashMap<String, ModelInstrument>();
-    private Map<String, ModelInstrument> loadedlist
-            = new HashMap<String, ModelInstrument>();
-
-    private ArrayList<Receiver> recvslist = new ArrayList<Receiver>();
-
-    private void getBuffers(ModelInstrument instrument,
-            List<ModelByteBuffer> buffers) {
-        for (ModelPerformer performer : instrument.getPerformers()) {
-            if (performer.getOscillators() != null) {
-                for (ModelOscillator osc : performer.getOscillators()) {
-                    if (osc instanceof ModelByteBufferWavetable) {
-                        ModelByteBufferWavetable w = (ModelByteBufferWavetable)osc;
-                        ModelByteBuffer buff = w.getBuffer();
-                        if (buff != null)
-                            buffers.add(buff);
-                        buff = w.get8BitExtensionBuffer();
-                        if (buff != null)
-                            buffers.add(buff);
-                    }
-                }
-            }
-        }
-    }
-
-    private boolean loadSamples(List<ModelInstrument> instruments) {
-        if (largemode)
-            return true;
-        List<ModelByteBuffer> buffers = new ArrayList<ModelByteBuffer>();
-        for (ModelInstrument instrument : instruments)
-            getBuffers(instrument, buffers);
-        try {
-            ModelByteBuffer.loadAll(buffers);
-        } catch (IOException e) {
-            return false;
-        }
-        return true;
-    }
-
-    private boolean loadInstruments(List<ModelInstrument> instruments) {
-        if (!isOpen())
-            return false;
-        if (!loadSamples(instruments))
-            return false;
-
-        synchronized (control_mutex) {
-            if (channels != null)
-                for (SoftChannel c : channels)
-                    c.current_instrument = null;
-            for (Instrument instrument : instruments) {
-                String pat = patchToString(instrument.getPatch());
-                availlist.remove(pat);
-                SoftInstrument softins
-                        = new SoftInstrument((ModelInstrument) instrument);
-                inslist.put(pat, softins);
-                loadedlist.put(pat, (ModelInstrument) instrument);
-            }
-        }
-
-        return true;
-    }
-
-    private void processPropertyInfo(Map<String, Object> info)	{
-        AudioSynthesizerPropertyInfo[] items = getPropertyInfo(info);
-
-        String resamplerType = (String)items[0].value;
-        if (resamplerType.equalsIgnoreCase("point"))
-            this.resampler = new SoftPointResampler();
-        else if (resamplerType.equalsIgnoreCase("linear"))
-            this.resampler = new SoftLinearResampler2();
-        else if (resamplerType.equalsIgnoreCase("linear1"))
-            this.resampler = new SoftLinearResampler();
-        else if (resamplerType.equalsIgnoreCase("linear2"))
-            this.resampler = new SoftLinearResampler2();
-        else if (resamplerType.equalsIgnoreCase("cubic"))
-            this.resampler = new SoftCubicResampler();
-        else if (resamplerType.equalsIgnoreCase("lanczos"))
-            this.resampler = new SoftLanczosResampler();
-        else if (resamplerType.equalsIgnoreCase("sinc"))
-            this.resampler = new SoftSincResampler();
-
-        setFormat((AudioFormat)items[2].value);
-        controlrate = (Float)items[1].value;
-        latency = (Long)items[3].value;
-        deviceid = (Integer)items[4].value;
-        maxpoly = (Integer)items[5].value;
-        reverb_on = (Boolean)items[6].value;
-        chorus_on = (Boolean)items[7].value;
-        agc_on = (Boolean)items[8].value;
-        largemode = (Boolean)items[9].value;
-        number_of_midi_channels = (Integer)items[10].value;
-        jitter_correction = (Boolean)items[11].value;
-    }
-
-    private String patchToString(Patch patch) {
-        if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion())
-            return "p." + patch.getProgram() + "." + patch.getBank();
-        else
-            return patch.getProgram() + "." + patch.getBank();
-    }
-
-    private void setFormat(AudioFormat format) {
-        if (format.getChannels() > 2) {
-            throw new IllegalArgumentException(
-                    "Only mono and stereo audio supported.");
-        }
-        if (AudioFloatConverter.getConverter(format) == null)
-            throw new IllegalArgumentException("Audio format not supported.");
-        this.format = format;
-    }
-
-    protected void removeReceiver(Receiver recv) {
-        boolean perform_close = false;
-        synchronized (control_mutex) {
-            if (recvslist.remove(recv)) {
-                if (implicitOpen && recvslist.isEmpty())
-                    perform_close = true;
-            }
-        }
-        if (perform_close)
-            close();
-    }
-
-    protected SoftMainMixer getMainMixer() {
-        if (!isOpen())
-            return null;
-        return mainmixer;
-    }
-
-    protected SoftInstrument findInstrument(int program, int bank, int channel) {
-
-        // Add support for GM2 banks 0x78 and 0x79
-        // as specified in DLS 2.2 in Section 1.4.6
-        // which allows using percussion and melodic instruments
-        // on all channels
-        if (bank >> 7 == 0x78 || bank >> 7 == 0x79) {
-            SoftInstrument current_instrument
-                    = inslist.get(program + "." + bank);
-            if (current_instrument != null)
-                return current_instrument;
-
-            String p_plaf;
-            if (bank >> 7 == 0x78)
-                p_plaf = "p.";
-            else
-                p_plaf = "";
-
-            // Instrument not found fallback to MSB:bank, LSB:0
-            current_instrument = inslist.get(p_plaf + program + "."
-                    + ((bank & 128) << 7));
-            if (current_instrument != null)
-                return current_instrument;
-            // Instrument not found fallback to MSB:0, LSB:bank
-            current_instrument = inslist.get(p_plaf + program + "."
-                    + (bank & 128));
-            if (current_instrument != null)
-                return current_instrument;
-            // Instrument not found fallback to MSB:0, LSB:0
-            current_instrument = inslist.get(p_plaf + program + ".0");
-            if (current_instrument != null)
-                return current_instrument;
-            // Instrument not found fallback to MSB:0, LSB:0, program=0
-            current_instrument = inslist.get(p_plaf + program + "0.0");
-            if (current_instrument != null)
-                return current_instrument;
-            return null;
-        }
-
-        // Channel 10 uses percussion instruments
-        String p_plaf;
-        if (channel == 9)
-            p_plaf = "p.";
-        else
-            p_plaf = "";
-
-        SoftInstrument current_instrument
-                = inslist.get(p_plaf + program + "." + bank);
-        if (current_instrument != null)
-            return current_instrument;
-        // Instrument not found fallback to MSB:0, LSB:0
-        current_instrument = inslist.get(p_plaf + program + ".0");
-        if (current_instrument != null)
-            return current_instrument;
-        // Instrument not found fallback to MSB:0, LSB:0, program=0
-        current_instrument = inslist.get(p_plaf + "0.0");
-        if (current_instrument != null)
-            return current_instrument;
-        return null;
-    }
-
-    protected int getVoiceAllocationMode() {
-        return voice_allocation_mode;
-    }
-
-    protected int getGeneralMidiMode() {
-        return gmmode;
-    }
-
-    protected void setGeneralMidiMode(int gmmode) {
-        this.gmmode = gmmode;
-    }
-
-    protected int getDeviceID() {
-        return deviceid;
-    }
-
-    protected float getControlRate() {
-        return controlrate;
-    }
-
-    protected SoftVoice[] getVoices() {
-        return voices;
-    }
-
-    protected SoftTuning getTuning(Patch patch) {
-        String t_id = patchToString(patch);
-        SoftTuning tuning = tunings.get(t_id);
-        if (tuning == null) {
-            tuning = new SoftTuning(patch);
-            tunings.put(t_id, tuning);
-        }
-        return tuning;
-    }
-
-    public long getLatency() {
-        synchronized (control_mutex) {
-            return latency;
-        }
-    }
-
-    public AudioFormat getFormat() {
-        synchronized (control_mutex) {
-            return format;
-        }
-    }
-
-    public int getMaxPolyphony() {
-        synchronized (control_mutex) {
-            return maxpoly;
-        }
-    }
-
-    public MidiChannel[] getChannels() {
-
-        synchronized (control_mutex) {
-            // if (external_channels == null) => the synthesizer is not open,
-            // create 16 proxy channels
-            // otherwise external_channels has the same length as channels array
-            if (external_channels == null) {
-                external_channels = new SoftChannelProxy[16];
-                for (int i = 0; i < external_channels.length; i++)
-                    external_channels[i] = new SoftChannelProxy();
-            }
-            MidiChannel[] ret;
-            if (isOpen())
-                ret = new MidiChannel[channels.length];
-            else
-                ret = new MidiChannel[16];
-            for (int i = 0; i < ret.length; i++)
-                ret[i] = external_channels[i];
-            return ret;
-        }
-    }
-
-    public VoiceStatus[] getVoiceStatus() {
-        if (!isOpen()) {
-            VoiceStatus[] tempVoiceStatusArray
-                    = new VoiceStatus[getMaxPolyphony()];
-            for (int i = 0; i < tempVoiceStatusArray.length; i++) {
-                VoiceStatus b = new VoiceStatus();
-                b.active = false;
-                b.bank = 0;
-                b.channel = 0;
-                b.note = 0;
-                b.program = 0;
-                b.volume = 0;
-                tempVoiceStatusArray[i] = b;
-            }
-            return tempVoiceStatusArray;
-        }
-
-        synchronized (control_mutex) {
-            VoiceStatus[] tempVoiceStatusArray = new VoiceStatus[voices.length];
-            for (int i = 0; i < voices.length; i++) {
-                VoiceStatus a = voices[i];
-                VoiceStatus b = new VoiceStatus();
-                b.active = a.active;
-                b.bank = a.bank;
-                b.channel = a.channel;
-                b.note = a.note;
-                b.program = a.program;
-                b.volume = a.volume;
-                tempVoiceStatusArray[i] = b;
-            }
-            return tempVoiceStatusArray;
-        }
-    }
-
-    public boolean isSoundbankSupported(Soundbank soundbank) {
-        for (Instrument ins: soundbank.getInstruments())
-            if (!(ins instanceof ModelInstrument))
-                return false;
-        return true;
-    }
-
-    public boolean loadInstrument(Instrument instrument) {
-        if (instrument == null || (!(instrument instanceof ModelInstrument))) {
-            throw new IllegalArgumentException("Unsupported instrument: " +
-                    instrument.toString());
-        }
-        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
-        instruments.add((ModelInstrument)instrument);
-        return loadInstruments(instruments);
-    }
-
-    public void unloadInstrument(Instrument instrument) {
-        if (instrument == null || (!(instrument instanceof ModelInstrument))) {
-            throw new IllegalArgumentException("Unsupported instrument: " +
-                    instrument.toString());
-        }
-        if (!isOpen())
-            return;
-
-        String pat = patchToString(instrument.getPatch());
-        synchronized (control_mutex) {
-            for (SoftChannel c: channels)
-                c.current_instrument = null;
-            inslist.remove(pat);
-            loadedlist.remove(pat);
-            availlist.remove(pat);
-        }
-    }
-
-    public boolean remapInstrument(Instrument from, Instrument to) {
-
-        if (from == null)
-            throw new NullPointerException();
-        if (to == null)
-            throw new NullPointerException();
-        if (!(from instanceof ModelInstrument)) {
-            throw new IllegalArgumentException("Unsupported instrument: " +
-                    from.toString());
-        }
-        if (!(to instanceof ModelInstrument)) {
-            throw new IllegalArgumentException("Unsupported instrument: " +
-                    to.toString());
-        }
-        if (!isOpen())
-            return false;
-
-        synchronized (control_mutex) {
-            if (!loadedlist.containsValue(to) && !availlist.containsValue(to))
-                throw new IllegalArgumentException("Instrument to is not loaded.");
-            unloadInstrument(from);
-            ModelMappedInstrument mfrom = new ModelMappedInstrument(
-                    (ModelInstrument)to, from.getPatch());
-            return loadInstrument(mfrom);
-        }
-    }
-
-    public synchronized Soundbank getDefaultSoundbank() {
-        if (defaultSoundBank == null) {
-            try {
-                File javahome = new File(System.getProperties().getProperty(
-                        "java.home"));
-                File libaudio = new File(new File(javahome, "lib"), "audio");
-
-                if (libaudio.exists()) {
-                    File foundfile = null;
-                    File[] files = libaudio.listFiles();
-                    if (files != null) {
-                        for (int i = 0; i < files.length; i++) {
-                            File file = files[i];
-                            if (file.isFile()) {
-                                String lname = file.getName().toLowerCase();
-                                if (lname.endsWith(".sf2") ||
-                                        lname.endsWith(".dls")) {
-                                    if (foundfile == null || (file.length() >
-                                            foundfile.length())) {
-                                        foundfile = file;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                    if (foundfile != null) {
-                        try {
-                            Soundbank sbk = MidiSystem.getSoundbank(foundfile);
-                            defaultSoundBank = sbk;
-                            return defaultSoundBank;
-                        } catch (Exception e) {
-                            //e.printStackTrace();
-                        }
-                    }
-                }
-
-                if (System.getProperties().getProperty("os.name")
-                        .startsWith("Windows")) {
-                    File gm_dls = new File(System.getenv("SystemRoot")
-                            + "\\system32\\drivers\\gm.dls");
-                    if (gm_dls.exists()) {
-                        try {
-                            Soundbank sbk = MidiSystem.getSoundbank(gm_dls);
-                            defaultSoundBank = sbk;
-                            return defaultSoundBank;
-                        } catch (Exception e) {
-                            //e.printStackTrace();
-                        }
-                    }
-                }
-            } catch (AccessControlException e) {
-            } catch (Exception e) {
-                //e.printStackTrace();
-            }
-
-            try {
-                defaultSoundBank = EmergencySoundbank.createSoundbank();
-            } catch (Exception e) {
-                //e.printStackTrace();
-            }
-
-        }
-        return defaultSoundBank;
-    }
-
-    public Instrument[] getAvailableInstruments() {
-        if (!isOpen()) {
-            Soundbank defsbk = getDefaultSoundbank();
-            if (defsbk == null)
-                return new Instrument[0];
-            return defsbk.getInstruments();
-        }
-
-        synchronized (control_mutex) {
-            ModelInstrument[] inslist_array =
-                    new ModelInstrument[availlist.values().size()];
-            availlist.values().toArray(inslist_array);
-            Arrays.sort(inslist_array, new ModelInstrumentComparator());
-            return inslist_array;
-        }
-    }
-
-    public Instrument[] getLoadedInstruments() {
-        if (!isOpen())
-            return new Instrument[0];
-
-        synchronized (control_mutex) {
-            ModelInstrument[] inslist_array =
-                    new ModelInstrument[loadedlist.values().size()];
-            loadedlist.values().toArray(inslist_array);
-            Arrays.sort(inslist_array, new ModelInstrumentComparator());
-            return inslist_array;
-        }
-    }
-
-    public boolean loadAllInstruments(Soundbank soundbank) {
-        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
-        for (Instrument ins: soundbank.getInstruments()) {
-            if (ins == null || !(ins instanceof ModelInstrument)) {
-                throw new IllegalArgumentException(
-                        "Unsupported instrument: " + ins);
-            }
-            instruments.add((ModelInstrument)ins);
-        }
-        return loadInstruments(instruments);
-    }
-
-    public void unloadAllInstruments(Soundbank soundbank) {
-        if (!isOpen())
-            return;
-
-        for (Instrument ins: soundbank.getInstruments()) {
-            if (ins instanceof ModelInstrument) {
-                unloadInstrument(ins);
-            }
-        }
-    }
-
-    public boolean loadInstruments(Soundbank soundbank, Patch[] patchList) {
-        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
-        for (Patch patch: patchList) {
-            Instrument ins = soundbank.getInstrument(patch);
-            if (ins == null || !(ins instanceof ModelInstrument)) {
-                throw new IllegalArgumentException(
-                        "Unsupported instrument: " + ins);
-            }
-            instruments.add((ModelInstrument)ins);
-        }
-        return loadInstruments(instruments);
-    }
-
-    public void unloadInstruments(Soundbank soundbank, Patch[] patchList) {
-        if (!isOpen())
-            return;
-
-        for (Patch pat: patchList) {
-            Instrument ins = soundbank.getInstrument(pat);
-            if (ins instanceof ModelInstrument) {
-                unloadInstrument(ins);
-            }
-        }
-    }
-
-    public MidiDevice.Info getDeviceInfo() {
-        return info;
-    }
-
-    public AudioSynthesizerPropertyInfo[] getPropertyInfo(Map<String, Object> info) {
-        List<AudioSynthesizerPropertyInfo> list =
-                new ArrayList<AudioSynthesizerPropertyInfo>();
-
-        AudioSynthesizerPropertyInfo item;
-
-        item = new AudioSynthesizerPropertyInfo("interpolation", "linear");
-        item.choices = new String[]{"linear", "linear1", "linear2", "cubic",
-                                    "lanczos", "sinc", "point"};
-        item.description = "Interpolation method";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("control rate", 147f);
-        item.description = "Control rate";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("format",
-                new AudioFormat(44100, 16, 2, true, false));
-        item.description = "Default audio format";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("latency", 120000L);
-        item.description = "Default latency";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("device id", 0);
-        item.description = "Device ID for SysEx Messages";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("max polyphony", 64);
-        item.description = "Maximum polyphony";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("reverb", true);
-        item.description = "Turn reverb effect on or off";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("chorus", true);
-        item.description = "Turn chorus effect on or off";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("auto gain control", true);
-        item.description = "Turn auto gain control on or off";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("large mode", false);
-        item.description = "Turn large mode on or off.";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("midi channels", 16);
-        item.description = "Number of midi channels.";
-        list.add(item);
-
-        item = new AudioSynthesizerPropertyInfo("jitter correction", true);
-        item.description = "Turn jitter correction on or off.";
-        list.add(item);
-
-        AudioSynthesizerPropertyInfo[] items;
-        items = list.toArray(new AudioSynthesizerPropertyInfo[list.size()]);
-
-        if (info != null)
-            for (AudioSynthesizerPropertyInfo item2: items) {
-                Object v = info.get(item2.name);
-                Class c = (item2.valueClass);
-                if (v != null)
-                    if (c.isInstance(v))
-                        item2.value = v;
-            }
-
-        return items;
-    }
-
-    public void open() throws MidiUnavailableException {
-        if (isOpen()) {
-            synchronized (control_mutex) {
-                implicitOpen = false;
-            }
-            return;
-        }
-        open(null, null);
-    }
-
-    public void open(SourceDataLine line, Map<String, Object> info) throws MidiUnavailableException {
-        if (isOpen()) {
-            synchronized (control_mutex) {
-                implicitOpen = false;
-            }
-            return;
-        }
-        synchronized (control_mutex) {
-            try {
-                if (line != null)
-                    setFormat(line.getFormat());
-
-                AudioInputStream ais = openStream(getFormat(), info);
-
-                if (line == null)
-                    line = AudioSystem.getSourceDataLine(getFormat());
-
-                double latency = this.latency;
-
-                if (!line.isOpen()) {
-                    int bufferSize = getFormat().getFrameSize()
-                        * (int)(getFormat().getFrameRate() * (latency/1000000f));
-                    line.open(getFormat(), bufferSize);
-
-                    // Remember that we opened that line
-                    // so we can close again in SoftSynthesizer.close()
-                    sourceDataLine = line;
-                }
-                if (!line.isActive())
-                    line.start();
-
-                int controlbuffersize = 512;
-                try {
-                    controlbuffersize = ais.available();
-                } catch (IOException e) {
-                }
-
-                // Tell mixer not fill read buffers fully.
-                // This lowers latency, and tells DataPusher
-                // to read in smaller amounts.
-                //mainmixer.readfully = false;
-                //pusher = new DataPusher(line, ais);
-
-                int buffersize = line.getBufferSize();
-                buffersize -= buffersize % controlbuffersize;
-
-                if (buffersize < 3 * controlbuffersize)
-                    buffersize = 3 * controlbuffersize;
-
-                if (jitter_correction) {
-                    ais = new SoftJitterCorrector(ais, buffersize,
-                            controlbuffersize);
-                }
-                pusher = new SoftAudioPusher(line, ais, controlbuffersize);
-                pusher_stream = ais;
-                pusher.start();
-
-
-            } catch (LineUnavailableException e) {
-                if (isOpen())
-                    close();
-                // am: need MidiUnavailableException(Throwable) ctor!
-                throw new MidiUnavailableException(e.toString());
-            }
-
-        }
-    }
-
-    public AudioInputStream openStream(AudioFormat targetFormat,
-            Map<String, Object> info) throws MidiUnavailableException {
-
-        if (isOpen())
-            throw new MidiUnavailableException("Synthesizer is already open");
-
-        synchronized (control_mutex) {
-            open = true;
-            implicitOpen = false;
-
-            gmmode = 0;
-            voice_allocation_mode = 0;
-
-            processPropertyInfo(info);
-            if (targetFormat != null)
-                setFormat(targetFormat);
-
-            Soundbank defbank = getDefaultSoundbank();
-            if (defbank != null) {
-                loadAllInstruments(defbank);
-                availlist.putAll(loadedlist);
-                loadedlist.clear();
-            }
-
-            voices = new SoftVoice[maxpoly];
-            for (int i = 0; i < maxpoly; i++)
-                voices[i] = new SoftVoice(this);
-
-            mainmixer = new SoftMainMixer(this);
-
-            channels = new SoftChannel[number_of_midi_channels];
-            for (int i = 0; i < channels.length; i++)
-                channels[i] = new SoftChannel(this, i);
-
-            if (external_channels == null) {
-                // Always create external_channels array
-                // with 16 or more channels
-                // so getChannels works correctly
-                // when the synhtesizer is closed.
-                if (channels.length < 16)
-                    external_channels = new SoftChannelProxy[16];
-                else
-                    external_channels = new SoftChannelProxy[channels.length];
-                for (int i = 0; i < external_channels.length; i++)
-                    external_channels[i] = new SoftChannelProxy();
-            } else {
-                // We must resize external_channels array
-                // but we must also copy the old SoftChannelProxy
-                // into the new one
-                if (channels.length > external_channels.length) {
-                    SoftChannelProxy[] new_external_channels
-                            = new SoftChannelProxy[channels.length];
-                    for (int i = 0; i < external_channels.length; i++)
-                        new_external_channels[i] = external_channels[i];
-                    for (int i = external_channels.length;
-                            i < new_external_channels.length; i++) {
-                        new_external_channels[i] = new SoftChannelProxy();
-                    }
-                }
-            }
-
-            for (int i = 0; i < channels.length; i++)
-                external_channels[i].setChannel(channels[i]);
-
-            for (SoftVoice voice: getVoices())
-                voice.resampler = resampler.openStreamer();
-
-            for (Receiver recv: getReceivers()) {
-                SoftReceiver srecv = ((SoftReceiver)recv);
-                srecv.open = open;
-                srecv.mainmixer = mainmixer;
-                srecv.midimessages = mainmixer.midimessages;
-            }
-
-            return mainmixer.getInputStream();
-        }
-    }
-
-    public void close() {
-
-        if (!isOpen())
-            return;
-
-        SoftAudioPusher pusher_to_be_closed = null;
-        AudioInputStream pusher_stream_to_be_closed = null;
-        synchronized (control_mutex) {
-            if (pusher != null) {
-                pusher_to_be_closed = pusher;
-                pusher_stream_to_be_closed = pusher_stream;
-                pusher = null;
-                pusher_stream = null;
-            }
-        }
-
-        if (pusher_to_be_closed != null) {
-            // Pusher must not be closed synchronized against control_mutex,
-            // this may result in synchronized conflict between pusher
-            // and current thread.
-            pusher_to_be_closed.stop();
-
-            try {
-                pusher_stream_to_be_closed.close();
-            } catch (IOException e) {
-                //e.printStackTrace();
-            }
-        }
-
-        synchronized (control_mutex) {
-
-            if (mainmixer != null)
-                mainmixer.close();
-            open = false;
-            implicitOpen = false;
-            mainmixer = null;
-            voices = null;
-            channels = null;
-
-            if (external_channels != null)
-                for (int i = 0; i < external_channels.length; i++)
-                    external_channels[i].setChannel(null);
-
-            if (sourceDataLine != null) {
-                sourceDataLine.drain();
-                sourceDataLine.close();
-                sourceDataLine = null;
-            }
-
-            inslist.clear();
-            availlist.clear();
-            loadedlist.clear();
-            tunings.clear();
-
-            while (recvslist.size() != 0)
-                recvslist.get(recvslist.size() - 1).close();
-
-        }
-    }
-
-    public boolean isOpen() {
-        synchronized (control_mutex) {
-            return open;
-        }
-    }
-
-    public long getMicrosecondPosition() {
-
-        if (!isOpen())
-            return 0;
-
-        synchronized (control_mutex) {
-            return mainmixer.getMicrosecondPosition();
-        }
-    }
-
-    public int getMaxReceivers() {
-        return -1;
-    }
-
-    public int getMaxTransmitters() {
-        return 0;
-    }
-
-    public Receiver getReceiver() throws MidiUnavailableException {
-
-        synchronized (control_mutex) {
-            SoftReceiver receiver = new SoftReceiver(this);
-            receiver.open = open;
-            recvslist.add(receiver);
-            return receiver;
-        }
-    }
-
-    public List<Receiver> getReceivers() {
-
-        synchronized (control_mutex) {
-            ArrayList<Receiver> recvs = new ArrayList<Receiver>();
-            recvs.addAll(recvslist);
-            return recvs;
-        }
-    }
-
-    public Transmitter getTransmitter() throws MidiUnavailableException {
-
-        throw new MidiUnavailableException("No transmitter available");
-    }
-
-    public List<Transmitter> getTransmitters() {
-
-        return new ArrayList<Transmitter>();
-    }
-
-    public Receiver getReceiverReferenceCounting()
-            throws MidiUnavailableException {
-
-        if (!isOpen()) {
-            open();
-            synchronized (control_mutex) {
-                implicitOpen = true;
-            }
-        }
-
-        return getReceiver();
-    }
-
-    public Transmitter getTransmitterReferenceCounting()
-            throws MidiUnavailableException {
-
-        throw new MidiUnavailableException("No transmitter available");
-    }
-}
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.media.sound;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.AccessControlException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.sound.midi.Instrument;
+import javax.sound.midi.MidiChannel;
+import javax.sound.midi.MidiDevice;
+import javax.sound.midi.MidiSystem;
+import javax.sound.midi.MidiUnavailableException;
+import javax.sound.midi.Patch;
+import javax.sound.midi.Receiver;
+import javax.sound.midi.Soundbank;
+import javax.sound.midi.Transmitter;
+import javax.sound.midi.VoiceStatus;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.SourceDataLine;
+
+/**
+ * The software synthesizer class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftSynthesizer implements AudioSynthesizer,
+        ReferenceCountingDevice {
+
+    private static class Info extends MidiDevice.Info {
+        public Info() {
+            super(INFO_NAME, INFO_VENDOR, INFO_DESCRIPTION, INFO_VERSION);
+        }
+    }
+
+    protected static final String INFO_NAME = "Gervill";
+    protected static final String INFO_VENDOR = "OpenJDK";
+    protected static final String INFO_DESCRIPTION = "Software MIDI Synthesizer";
+    protected static final String INFO_VERSION = "1.0";
+    protected static MidiDevice.Info info = new Info();
+
+    private static Soundbank defaultSoundBank = null;
+
+    protected Object control_mutex = this;
+
+    protected int voiceIDCounter = 0;
+
+    // 0: default
+    // 1: DLS Voice Allocation
+    protected int voice_allocation_mode = 0;
+
+    protected boolean reverb_on = true;
+    protected boolean chorus_on = true;
+    protected boolean agc_on = true;
+
+    protected SoftChannel[] channels;
+    protected SoftChannelProxy[] external_channels = null;
+
+    private boolean largemode = false;
+
+    // 0: GM Mode off (default)
+    // 1: GM Level 1
+    // 2: GM Level 2
+    private int gmmode = 0;
+
+    private int deviceid = 0;
+
+    private AudioFormat format = new AudioFormat(44100, 16, 2, true, false);
+
+    private SourceDataLine sourceDataLine = null;
+
+    private SoftAudioPusher pusher = null;
+    private AudioInputStream pusher_stream = null;
+
+    private float controlrate = 147f;
+
+    private boolean open = false;
+    private boolean implicitOpen = false;
+
+    private SoftResampler resampler = new SoftLinearResampler();
+
+    private int number_of_midi_channels = 16;
+    private int maxpoly = 64;
+    private long latency = 200000; // 200 msec
+    private boolean jitter_correction = false;
+
+    private SoftMainMixer mainmixer;
+    private SoftVoice[] voices;
+
+    private Map<String, SoftTuning> tunings
+            = new HashMap<String, SoftTuning>();
+    private Map<String, SoftInstrument> inslist
+            = new HashMap<String, SoftInstrument>();
+    private Map<String, ModelInstrument> availlist
+            = new HashMap<String, ModelInstrument>();
+    private Map<String, ModelInstrument> loadedlist
+            = new HashMap<String, ModelInstrument>();
+
+    private ArrayList<Receiver> recvslist = new ArrayList<Receiver>();
+
+    private void getBuffers(ModelInstrument instrument,
+            List<ModelByteBuffer> buffers) {
+        for (ModelPerformer performer : instrument.getPerformers()) {
+            if (performer.getOscillators() != null) {
+                for (ModelOscillator osc : performer.getOscillators()) {
+                    if (osc instanceof ModelByteBufferWavetable) {
+                        ModelByteBufferWavetable w = (ModelByteBufferWavetable)osc;
+                        ModelByteBuffer buff = w.getBuffer();
+                        if (buff != null)
+                            buffers.add(buff);
+                        buff = w.get8BitExtensionBuffer();
+                        if (buff != null)
+                            buffers.add(buff);
+                    }
+                }
+            }
+        }
+    }
+
+    private boolean loadSamples(List<ModelInstrument> instruments) {
+        if (largemode)
+            return true;
+        List<ModelByteBuffer> buffers = new ArrayList<ModelByteBuffer>();
+        for (ModelInstrument instrument : instruments)
+            getBuffers(instrument, buffers);
+        try {
+            ModelByteBuffer.loadAll(buffers);
+        } catch (IOException e) {
+            return false;
+        }
+        return true;
+    }
+
+    private boolean loadInstruments(List<ModelInstrument> instruments) {
+        if (!isOpen())
+            return false;
+        if (!loadSamples(instruments))
+            return false;
+
+        synchronized (control_mutex) {
+            if (channels != null)
+                for (SoftChannel c : channels)
+                    c.current_instrument = null;
+            for (Instrument instrument : instruments) {
+                String pat = patchToString(instrument.getPatch());
+                availlist.remove(pat);
+                SoftInstrument softins
+                        = new SoftInstrument((ModelInstrument) instrument);
+                inslist.put(pat, softins);
+                loadedlist.put(pat, (ModelInstrument) instrument);
+            }
+        }
+
+        return true;
+    }
+
+    private void processPropertyInfo(Map<String, Object> info)  {
+        AudioSynthesizerPropertyInfo[] items = getPropertyInfo(info);
+
+        String resamplerType = (String)items[0].value;
+        if (resamplerType.equalsIgnoreCase("point"))
+            this.resampler = new SoftPointResampler();
+        else if (resamplerType.equalsIgnoreCase("linear"))
+            this.resampler = new SoftLinearResampler2();
+        else if (resamplerType.equalsIgnoreCase("linear1"))
+            this.resampler = new SoftLinearResampler();
+        else if (resamplerType.equalsIgnoreCase("linear2"))
+            this.resampler = new SoftLinearResampler2();
+        else if (resamplerType.equalsIgnoreCase("cubic"))
+            this.resampler = new SoftCubicResampler();
+        else if (resamplerType.equalsIgnoreCase("lanczos"))
+            this.resampler = new SoftLanczosResampler();
+        else if (resamplerType.equalsIgnoreCase("sinc"))
+            this.resampler = new SoftSincResampler();
+
+        setFormat((AudioFormat)items[2].value);
+        controlrate = (Float)items[1].value;
+        latency = (Long)items[3].value;
+        deviceid = (Integer)items[4].value;
+        maxpoly = (Integer)items[5].value;
+        reverb_on = (Boolean)items[6].value;
+        chorus_on = (Boolean)items[7].value;
+        agc_on = (Boolean)items[8].value;
+        largemode = (Boolean)items[9].value;
+        number_of_midi_channels = (Integer)items[10].value;
+        jitter_correction = (Boolean)items[11].value;
+    }
+
+    private String patchToString(Patch patch) {
+        if (patch instanceof ModelPatch && ((ModelPatch) patch).isPercussion())
+            return "p." + patch.getProgram() + "." + patch.getBank();
+        else
+            return patch.getProgram() + "." + patch.getBank();
+    }
+
+    private void setFormat(AudioFormat format) {
+        if (format.getChannels() > 2) {
+            throw new IllegalArgumentException(
+                    "Only mono and stereo audio supported.");
+        }
+        if (AudioFloatConverter.getConverter(format) == null)
+            throw new IllegalArgumentException("Audio format not supported.");
+        this.format = format;
+    }
+
+    protected void removeReceiver(Receiver recv) {
+        boolean perform_close = false;
+        synchronized (control_mutex) {
+            if (recvslist.remove(recv)) {
+                if (implicitOpen && recvslist.isEmpty())
+                    perform_close = true;
+            }
+        }
+        if (perform_close)
+            close();
+    }
+
+    protected SoftMainMixer getMainMixer() {
+        if (!isOpen())
+            return null;
+        return mainmixer;
+    }
+
+    protected SoftInstrument findInstrument(int program, int bank, int channel) {
+
+        // Add support for GM2 banks 0x78 and 0x79
+        // as specified in DLS 2.2 in Section 1.4.6
+        // which allows using percussion and melodic instruments
+        // on all channels
+        if (bank >> 7 == 0x78 || bank >> 7 == 0x79) {
+            SoftInstrument current_instrument
+                    = inslist.get(program + "." + bank);
+            if (current_instrument != null)
+                return current_instrument;
+
+            String p_plaf;
+            if (bank >> 7 == 0x78)
+                p_plaf = "p.";
+            else
+                p_plaf = "";
+
+            // Instrument not found fallback to MSB:bank, LSB:0
+            current_instrument = inslist.get(p_plaf + program + "."
+                    + ((bank & 128) << 7));
+            if (current_instrument != null)
+                return current_instrument;
+            // Instrument not found fallback to MSB:0, LSB:bank
+            current_instrument = inslist.get(p_plaf + program + "."
+                    + (bank & 128));
+            if (current_instrument != null)
+                return current_instrument;
+            // Instrument not found fallback to MSB:0, LSB:0
+            current_instrument = inslist.get(p_plaf + program + ".0");
+            if (current_instrument != null)
+                return current_instrument;
+            // Instrument not found fallback to MSB:0, LSB:0, program=0
+            current_instrument = inslist.get(p_plaf + program + "0.0");
+            if (current_instrument != null)
+                return current_instrument;
+            return null;
+        }
+
+        // Channel 10 uses percussion instruments
+        String p_plaf;
+        if (channel == 9)
+            p_plaf = "p.";
+        else
+            p_plaf = "";
+
+        SoftInstrument current_instrument
+                = inslist.get(p_plaf + program + "." + bank);
+        if (current_instrument != null)
+            return current_instrument;
+        // Instrument not found fallback to MSB:0, LSB:0
+        current_instrument = inslist.get(p_plaf + program + ".0");
+        if (current_instrument != null)
+            return current_instrument;
+        // Instrument not found fallback to MSB:0, LSB:0, program=0
+        current_instrument = inslist.get(p_plaf + "0.0");
+        if (current_instrument != null)
+            return current_instrument;
+        return null;
+    }
+
+    protected int getVoiceAllocationMode() {
+        return voice_allocation_mode;
+    }
+
+    protected int getGeneralMidiMode() {
+        return gmmode;
+    }
+
+    protected void setGeneralMidiMode(int gmmode) {
+        this.gmmode = gmmode;
+    }
+
+    protected int getDeviceID() {
+        return deviceid;
+    }
+
+    protected float getControlRate() {
+        return controlrate;
+    }
+
+    protected SoftVoice[] getVoices() {
+        return voices;
+    }
+
+    protected SoftTuning getTuning(Patch patch) {
+        String t_id = patchToString(patch);
+        SoftTuning tuning = tunings.get(t_id);
+        if (tuning == null) {
+            tuning = new SoftTuning(patch);
+            tunings.put(t_id, tuning);
+        }
+        return tuning;
+    }
+
+    public long getLatency() {
+        synchronized (control_mutex) {
+            return latency;
+        }
+    }
+
+    public AudioFormat getFormat() {
+        synchronized (control_mutex) {
+            return format;
+        }
+    }
+
+    public int getMaxPolyphony() {
+        synchronized (control_mutex) {
+            return maxpoly;
+        }
+    }
+
+    public MidiChannel[] getChannels() {
+
+        synchronized (control_mutex) {
+            // if (external_channels == null) => the synthesizer is not open,
+            // create 16 proxy channels
+            // otherwise external_channels has the same length as channels array
+            if (external_channels == null) {
+                external_channels = new SoftChannelProxy[16];
+                for (int i = 0; i < external_channels.length; i++)
+                    external_channels[i] = new SoftChannelProxy();
+            }
+            MidiChannel[] ret;
+            if (isOpen())
+                ret = new MidiChannel[channels.length];
+            else
+                ret = new MidiChannel[16];
+            for (int i = 0; i < ret.length; i++)
+                ret[i] = external_channels[i];
+            return ret;
+        }
+    }
+
+    public VoiceStatus[] getVoiceStatus() {
+        if (!isOpen()) {
+            VoiceStatus[] tempVoiceStatusArray
+                    = new VoiceStatus[getMaxPolyphony()];
+            for (int i = 0; i < tempVoiceStatusArray.length; i++) {
+                VoiceStatus b = new VoiceStatus();
+                b.active = false;
+                b.bank = 0;
+                b.channel = 0;
+                b.note = 0;
+                b.program = 0;
+                b.volume = 0;
+                tempVoiceStatusArray[i] = b;
+            }
+            return tempVoiceStatusArray;
+        }
+
+        synchronized (control_mutex) {
+            VoiceStatus[] tempVoiceStatusArray = new VoiceStatus[voices.length];
+            for (int i = 0; i < voices.length; i++) {
+                VoiceStatus a = voices[i];
+                VoiceStatus b = new VoiceStatus();
+                b.active = a.active;
+                b.bank = a.bank;
+                b.channel = a.channel;
+                b.note = a.note;
+                b.program = a.program;
+                b.volume = a.volume;
+                tempVoiceStatusArray[i] = b;
+            }
+            return tempVoiceStatusArray;
+        }
+    }
+
+    public boolean isSoundbankSupported(Soundbank soundbank) {
+        for (Instrument ins: soundbank.getInstruments())
+            if (!(ins instanceof ModelInstrument))
+                return false;
+        return true;
+    }
+
+    public boolean loadInstrument(Instrument instrument) {
+        if (instrument == null || (!(instrument instanceof ModelInstrument))) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    instrument.toString());
+        }
+        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
+        instruments.add((ModelInstrument)instrument);
+        return loadInstruments(instruments);
+    }
+
+    public void unloadInstrument(Instrument instrument) {
+        if (instrument == null || (!(instrument instanceof ModelInstrument))) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    instrument.toString());
+        }
+        if (!isOpen())
+            return;
+
+        String pat = patchToString(instrument.getPatch());
+        synchronized (control_mutex) {
+            for (SoftChannel c: channels)
+                c.current_instrument = null;
+            inslist.remove(pat);
+            loadedlist.remove(pat);
+            availlist.remove(pat);
+        }
+    }
+
+    public boolean remapInstrument(Instrument from, Instrument to) {
+
+        if (from == null)
+            throw new NullPointerException();
+        if (to == null)
+            throw new NullPointerException();
+        if (!(from instanceof ModelInstrument)) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    from.toString());
+        }
+        if (!(to instanceof ModelInstrument)) {
+            throw new IllegalArgumentException("Unsupported instrument: " +
+                    to.toString());
+        }
+        if (!isOpen())
+            return false;
+
+        synchronized (control_mutex) {
+            if (!loadedlist.containsValue(to) && !availlist.containsValue(to))
+                throw new IllegalArgumentException("Instrument to is not loaded.");
+            unloadInstrument(from);
+            ModelMappedInstrument mfrom = new ModelMappedInstrument(
+                    (ModelInstrument)to, from.getPatch());
+            return loadInstrument(mfrom);
+        }
+    }
+
+    public synchronized Soundbank getDefaultSoundbank() {
+        if (defaultSoundBank == null) {
+            try {
+                File javahome = new File(System.getProperties().getProperty(
+                        "java.home"));
+                File libaudio = new File(new File(javahome, "lib"), "audio");
+
+                if (libaudio.exists()) {
+                    File foundfile = null;
+                    File[] files = libaudio.listFiles();
+                    if (files != null) {
+                        for (int i = 0; i < files.length; i++) {
+                            File file = files[i];
+                            if (file.isFile()) {
+                                String lname = file.getName().toLowerCase();
+                                if (lname.endsWith(".sf2") ||
+                                        lname.endsWith(".dls")) {
+                                    if (foundfile == null || (file.length() >
+                                            foundfile.length())) {
+                                        foundfile = file;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (foundfile != null) {
+                        try {
+                            Soundbank sbk = MidiSystem.getSoundbank(foundfile);
+                            defaultSoundBank = sbk;
+                            return defaultSoundBank;
+                        } catch (Exception e) {
+                            //e.printStackTrace();
+                        }
+                    }
+                }
+
+                if (System.getProperties().getProperty("os.name")
+                        .startsWith("Windows")) {
+                    File gm_dls = new File(System.getenv("SystemRoot")
+                            + "\\system32\\drivers\\gm.dls");
+                    if (gm_dls.exists()) {
+                        try {
+                            Soundbank sbk = MidiSystem.getSoundbank(gm_dls);
+                            defaultSoundBank = sbk;
+                            return defaultSoundBank;
+                        } catch (Exception e) {
+                            //e.printStackTrace();
+                        }
+                    }
+                }
+            } catch (AccessControlException e) {
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+
+            try {
+                defaultSoundBank = EmergencySoundbank.createSoundbank();
+            } catch (Exception e) {
+                //e.printStackTrace();
+            }
+
+        }
+        return defaultSoundBank;
+    }
+
+    public Instrument[] getAvailableInstruments() {
+        if (!isOpen()) {
+            Soundbank defsbk = getDefaultSoundbank();
+            if (defsbk == null)
+                return new Instrument[0];
+            return defsbk.getInstruments();
+        }
+
+        synchronized (control_mutex) {
+            ModelInstrument[] inslist_array =
+                    new ModelInstrument[availlist.values().size()];
+            availlist.values().toArray(inslist_array);
+            Arrays.sort(inslist_array, new ModelInstrumentComparator());
+            return inslist_array;
+        }
+    }
+
+    public Instrument[] getLoadedInstruments() {
+        if (!isOpen())
+            return new Instrument[0];
+
+        synchronized (control_mutex) {
+            ModelInstrument[] inslist_array =
+                    new ModelInstrument[loadedlist.values().size()];
+            loadedlist.values().toArray(inslist_array);
+            Arrays.sort(inslist_array, new ModelInstrumentComparator());
+            return inslist_array;
+        }
+    }
+
+    public boolean loadAllInstruments(Soundbank soundbank) {
+        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
+        for (Instrument ins: soundbank.getInstruments()) {
+            if (ins == null || !(ins instanceof ModelInstrument)) {
+                throw new IllegalArgumentException(
+                        "Unsupported instrument: " + ins);
+            }
+            instruments.add((ModelInstrument)ins);
+        }
+        return loadInstruments(instruments);
+    }
+
+    public void unloadAllInstruments(Soundbank soundbank) {
+        if (!isOpen())
+            return;
+
+        for (Instrument ins: soundbank.getInstruments()) {
+            if (ins instanceof ModelInstrument) {
+                unloadInstrument(ins);
+            }
+        }
+    }
+
+    public boolean loadInstruments(Soundbank soundbank, Patch[] patchList) {
+        List<ModelInstrument> instruments = new ArrayList<ModelInstrument>();
+        for (Patch patch: patchList) {
+            Instrument ins = soundbank.getInstrument(patch);
+            if (ins == null || !(ins instanceof ModelInstrument)) {
+                throw new IllegalArgumentException(
+                        "Unsupported instrument: " + ins);
+            }
+            instruments.add((ModelInstrument)ins);
+        }
+        return loadInstruments(instruments);
+    }
+
+    public void unloadInstruments(Soundbank soundbank, Patch[] patchList) {
+        if (!isOpen())
+            return;
+
+        for (Patch pat: patchList) {
+            Instrument ins = soundbank.getInstrument(pat);
+            if (ins instanceof ModelInstrument) {
+                unloadInstrument(ins);
+            }
+        }
+    }
+
+    public MidiDevice.Info getDeviceInfo() {
+        return info;
+    }
+
+    public AudioSynthesizerPropertyInfo[] getPropertyInfo(Map<String, Object> info) {
+        List<AudioSynthesizerPropertyInfo> list =
+                new ArrayList<AudioSynthesizerPropertyInfo>();
+
+        AudioSynthesizerPropertyInfo item;
+
+        item = new AudioSynthesizerPropertyInfo("interpolation", "linear");
+        item.choices = new String[]{"linear", "linear1", "linear2", "cubic",
+                                    "lanczos", "sinc", "point"};
+        item.description = "Interpolation method";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("control rate", 147f);
+        item.description = "Control rate";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("format",
+                new AudioFormat(44100, 16, 2, true, false));
+        item.description = "Default audio format";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("latency", 120000L);
+        item.description = "Default latency";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("device id", 0);
+        item.description = "Device ID for SysEx Messages";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("max polyphony", 64);
+        item.description = "Maximum polyphony";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("reverb", true);
+        item.description = "Turn reverb effect on or off";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("chorus", true);
+        item.description = "Turn chorus effect on or off";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("auto gain control", true);
+        item.description = "Turn auto gain control on or off";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("large mode", false);
+        item.description = "Turn large mode on or off.";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("midi channels", 16);
+        item.description = "Number of midi channels.";
+        list.add(item);
+
+        item = new AudioSynthesizerPropertyInfo("jitter correction", true);
+        item.description = "Turn jitter correction on or off.";
+        list.add(item);
+
+        AudioSynthesizerPropertyInfo[] items;
+        items = list.toArray(new AudioSynthesizerPropertyInfo[list.size()]);
+
+        if (info != null)
+            for (AudioSynthesizerPropertyInfo item2: items) {
+                Object v = info.get(item2.name);
+                Class c = (item2.valueClass);
+                if (v != null)
+                    if (c.isInstance(v))
+                        item2.value = v;
+            }
+
+        return items;
+    }
+
+    public void open() throws MidiUnavailableException {
+        if (isOpen()) {
+            synchronized (control_mutex) {
+                implicitOpen = false;
+            }
+            return;
+        }
+        open(null, null);
+    }
+
+    public void open(SourceDataLine line, Map<String, Object> info) throws MidiUnavailableException {
+        if (isOpen()) {
+            synchronized (control_mutex) {
+                implicitOpen = false;
+            }
+            return;
+        }
+        synchronized (control_mutex) {
+            try {
+                if (line != null)
+                    setFormat(line.getFormat());
+
+                AudioInputStream ais = openStream(getFormat(), info);
+
+                if (line == null)
+                    line = AudioSystem.getSourceDataLine(getFormat());
+
+                double latency = this.latency;
+
+                if (!line.isOpen()) {
+                    int bufferSize = getFormat().getFrameSize()
+                        * (int)(getFormat().getFrameRate() * (latency/1000000f));
+                    line.open(getFormat(), bufferSize);
+
+                    // Remember that we opened that line
+                    // so we can close again in SoftSynthesizer.close()
+                    sourceDataLine = line;
+                }
+                if (!line.isActive())
+                    line.start();
+
+                int controlbuffersize = 512;
+                try {
+                    controlbuffersize = ais.available();
+                } catch (IOException e) {
+                }
+
+                // Tell mixer not fill read buffers fully.
+                // This lowers latency, and tells DataPusher
+                // to read in smaller amounts.
+                //mainmixer.readfully = false;
+                //pusher = new DataPusher(line, ais);
+
+                int buffersize = line.getBufferSize();
+                buffersize -= buffersize % controlbuffersize;
+
+                if (buffersize < 3 * controlbuffersize)
+                    buffersize = 3 * controlbuffersize;
+
+                if (jitter_correction) {
+                    ais = new SoftJitterCorrector(ais, buffersize,
+                            controlbuffersize);
+                }
+                pusher = new SoftAudioPusher(line, ais, controlbuffersize);
+                pusher_stream = ais;
+                pusher.start();
+
+
+            } catch (LineUnavailableException e) {
+                if (isOpen())
+                    close();
+                // am: need MidiUnavailableException(Throwable) ctor!
+                throw new MidiUnavailableException(e.toString());
+            }
+
+        }
+    }
+
+    public AudioInputStream openStream(AudioFormat targetFormat,
+            Map<String, Object> info) throws MidiUnavailableException {
+
+        if (isOpen())
+            throw new MidiUnavailableException("Synthesizer is already open");
+
+        synchronized (control_mutex) {
+            open = true;
+            implicitOpen = false;
+
+            gmmode = 0;
+            voice_allocation_mode = 0;
+
+            processPropertyInfo(info);
+            if (targetFormat != null)
+                setFormat(targetFormat);
+
+            Soundbank defbank = getDefaultSoundbank();
+            if (defbank != null) {
+                loadAllInstruments(defbank);
+                availlist.putAll(loadedlist);
+                loadedlist.clear();
+            }
+
+            voices = new SoftVoice[maxpoly];
+            for (int i = 0; i < maxpoly; i++)
+                voices[i] = new SoftVoice(this);
+
+            mainmixer = new SoftMainMixer(this);
+
+            channels = new SoftChannel[number_of_midi_channels];
+            for (int i = 0; i < channels.length; i++)
+                channels[i] = new SoftChannel(this, i);
+
+            if (external_channels == null) {
+                // Always create external_channels array
+                // with 16 or more channels
+                // so getChannels works correctly
+                // when the synhtesizer is closed.
+                if (channels.length < 16)
+                    external_channels = new SoftChannelProxy[16];
+                else
+                    external_channels = new SoftChannelProxy[channels.length];
+                for (int i = 0; i < external_channels.length; i++)
+                    external_channels[i] = new SoftChannelProxy();
+            } else {
+                // We must resize external_channels array
+                // but we must also copy the old SoftChannelProxy
+                // into the new one
+                if (channels.length > external_channels.length) {
+                    SoftChannelProxy[] new_external_channels
+                            = new SoftChannelProxy[channels.length];
+                    for (int i = 0; i < external_channels.length; i++)
+                        new_external_channels[i] = external_channels[i];
+                    for (int i = external_channels.length;
+                            i < new_external_channels.length; i++) {
+                        new_external_channels[i] = new SoftChannelProxy();
+                    }
+                }
+            }
+
+            for (int i = 0; i < channels.length; i++)
+                external_channels[i].setChannel(channels[i]);
+
+            for (SoftVoice voice: getVoices())
+                voice.resampler = resampler.openStreamer();
+
+            for (Receiver recv: getReceivers()) {
+                SoftReceiver srecv = ((SoftReceiver)recv);
+                srecv.open = open;
+                srecv.mainmixer = mainmixer;
+                srecv.midimessages = mainmixer.midimessages;
+            }
+
+            return mainmixer.getInputStream();
+        }
+    }
+
+    public void close() {
+
+        if (!isOpen())
+            return;
+
+        SoftAudioPusher pusher_to_be_closed = null;
+        AudioInputStream pusher_stream_to_be_closed = null;
+        synchronized (control_mutex) {
+            if (pusher != null) {
+                pusher_to_be_closed = pusher;
+                pusher_stream_to_be_closed = pusher_stream;
+                pusher = null;
+                pusher_stream = null;
+            }
+        }
+
+        if (pusher_to_be_closed != null) {
+            // Pusher must not be closed synchronized against control_mutex,
+            // this may result in synchronized conflict between pusher
+            // and current thread.
+            pusher_to_be_closed.stop();
+
+            try {
+                pusher_stream_to_be_closed.close();
+            } catch (IOException e) {
+                //e.printStackTrace();
+            }
+        }
+
+        synchronized (control_mutex) {
+
+            if (mainmixer != null)
+                mainmixer.close();
+            open = false;
+            implicitOpen = false;
+            mainmixer = null;
+            voices = null;
+            channels = null;
+
+            if (external_channels != null)
+                for (int i = 0; i < external_channels.length; i++)
+                    external_channels[i].setChannel(null);
+
+            if (sourceDataLine != null) {
+                sourceDataLine.drain();
+                sourceDataLine.close();
+                sourceDataLine = null;
+            }
+
+            inslist.clear();
+            availlist.clear();
+            loadedlist.clear();
+            tunings.clear();
+
+            while (recvslist.size() != 0)
+                recvslist.get(recvslist.size() - 1).close();
+
+        }
+    }
+
+    public boolean isOpen() {
+        synchronized (control_mutex) {
+            return open;
+        }
+    }
+
+    public long getMicrosecondPosition() {
+
+        if (!isOpen())
+            return 0;
+
+        synchronized (control_mutex) {
+            return mainmixer.getMicrosecondPosition();
+        }
+    }
+
+    public int getMaxReceivers() {
+        return -1;
+    }
+
+    public int getMaxTransmitters() {
+        return 0;
+    }
+
+    public Receiver getReceiver() throws MidiUnavailableException {
+
+        synchronized (control_mutex) {
+            SoftReceiver receiver = new SoftReceiver(this);
+            receiver.open = open;
+            recvslist.add(receiver);
+            return receiver;
+        }
+    }
+
+    public List<Receiver> getReceivers() {
+
+        synchronized (control_mutex) {
+            ArrayList<Receiver> recvs = new ArrayList<Receiver>();
+            recvs.addAll(recvslist);
+            return recvs;
+        }
+    }
+
+    public Transmitter getTransmitter() throws MidiUnavailableException {
+
+        throw new MidiUnavailableException("No transmitter available");
+    }
+
+    public List<Transmitter> getTransmitters() {
+
+        return new ArrayList<Transmitter>();
+    }
+
+    public Receiver getReceiverReferenceCounting()
+            throws MidiUnavailableException {
+
+        if (!isOpen()) {
+            open();
+            synchronized (control_mutex) {
+                implicitOpen = true;
+            }
+        }
+
+        return getReceiver();
+    }
+
+    public Transmitter getTransmitterReferenceCounting()
+            throws MidiUnavailableException {
+
+        throw new MidiUnavailableException("No transmitter available");
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftTuning.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftTuning.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,256 +1,256 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.UnsupportedEncodingException;
-
-import javax.sound.midi.Patch;
-
-/**
- * A tuning program container, for use with MIDI Tuning.
- * See: http://www.midi.org
- *
- * @author Karl Helgason
- */
-public class SoftTuning {
-
-    private String name = null;
-    private double[] tuning = new double[128];
-    private Patch patch = null;
-
-    public SoftTuning() {
-        name = "12-TET";
-        for (int i = 0; i < tuning.length; i++)
-            tuning[i] = i * 100;
-    }
-
-    public SoftTuning(byte[] data) {
-        for (int i = 0; i < tuning.length; i++)
-            tuning[i] = i * 100;
-        load(data);
-    }
-
-    public SoftTuning(Patch patch) {
-        this.patch = patch;
-        name = "12-TET";
-        for (int i = 0; i < tuning.length; i++)
-            tuning[i] = i * 100;
-    }
-
-    public SoftTuning(Patch patch, byte[] data) {
-        this.patch = patch;
-        for (int i = 0; i < tuning.length; i++)
-            tuning[i] = i * 100;
-        load(data);
-    }
-
-    private boolean checksumOK(byte[] data) {
-        int x = data[1] & 0xFF;
-        for (int i = 2; i < data.length - 2; i++)
-            x = x ^ (data[i] & 0xFF);
-        return (data[data.length - 2] & 0xFF) == (x & 127);
-    }
-
-    /*
-    private boolean checksumOK2(byte[] data) {
-        int x = data[1] & 0xFF; // 7E
-        x = x ^ (data[2] & 0xFF); // <device ID>
-        x = x ^ (data[4] & 0xFF); // nn
-        x = x ^ (data[5] & 0xFF); // tt
-        for (int i = 22; i < data.length - 2; i++)
-            x = x ^ (data[i] & 0xFF);
-        return (data[data.length - 2] & 0xFF) == (x & 127);
-    }
-     */
-    public void load(byte[] data) {
-        // Universal Non-Real-Time / Real-Time SysEx
-        if ((data[1] & 0xFF) == 0x7E || (data[1] & 0xFF) == 0x7F) {
-            int subid1 = data[3] & 0xFF;
-            switch (subid1) {
-            case 0x08: // MIDI Tuning Standard
-                int subid2 = data[4] & 0xFF;
-                switch (subid2) {
-                case 0x01: // BULK TUNING DUMP (NON-REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning.shtml
-                    //if (!checksumOK2(data))
-                    //	break;
-                    try {
-                        name = new String(data, 6, 16, "ascii");
-                    } catch (UnsupportedEncodingException e) {
-                        name = null;
-                    }
-                    int r = 22;
-                    for (int i = 0; i < 128; i++) {
-                        int xx = data[r++] & 0xFF;
-                        int yy = data[r++] & 0xFF;
-                        int zz = data[r++] & 0xFF;
-                        if (!(xx == 127 && yy == 127 && zz == 127))
-                            tuning[i] = 100.0 *
-                                    (((xx * 16384) + (yy * 128) + zz) / 16384.0);
-                    }
-                    break;
-                }
-                case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning.shtml
-                    int ll = data[6] & 0xFF;
-                    int r = 7;
-                    for (int i = 0; i < ll; i++) {
-                        int kk = data[r++] & 0xFF;
-                        int xx = data[r++] & 0xFF;
-                        int yy = data[r++] & 0xFF;
-                        int zz = data[r++] & 0xFF;
-                        if (!(xx == 127 && yy == 127 && zz == 127))
-                            tuning[kk] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
-                    }
-                    break;
-                }
-                case 0x04: // KEY-BASED TUNING DUMP (NON-REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning_extens.shtml
-                    if (!checksumOK(data))
-                        break;
-                    try {
-                        name = new String(data, 7, 16, "ascii");
-                    } catch (UnsupportedEncodingException e) {
-                        name = null;
-                    }
-                    int r = 23;
-                    for (int i = 0; i < 128; i++) {
-                        int xx = data[r++] & 0xFF;
-                        int yy = data[r++] & 0xFF;
-                        int zz = data[r++] & 0xFF;
-                        if (!(xx == 127 && yy == 127 && zz == 127))
-                            tuning[i] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
-                    }
-                    break;
-                }
-                case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
-                           // (NON-REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning_extens.shtml
-                    if (!checksumOK(data))
-                        break;
-                    try {
-                        name = new String(data, 7, 16, "ascii");
-                    } catch (UnsupportedEncodingException e) {
-                        name = null;
-                    }
-                    int[] octave_tuning = new int[12];
-                    for (int i = 0; i < 12; i++)
-                        octave_tuning[i] = (data[i + 23] & 0xFF) - 64;
-                    for (int i = 0; i < tuning.length; i++)
-                        tuning[i] = i * 100 + octave_tuning[i % 12];
-                    break;
-                }
-                case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
-                           // (NON-REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning_extens.shtml
-                    if (!checksumOK(data))
-                        break;
-                    try {
-                        name = new String(data, 7, 16, "ascii");
-                    } catch (UnsupportedEncodingException e) {
-                        name = null;
-                    }
-                    double[] octave_tuning = new double[12];
-                    for (int i = 0; i < 12; i++) {
-                        int v = (data[i * 2 + 23] & 0xFF) * 128
-                                + (data[i * 2 + 24] & 0xFF);
-                        octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
-                    }
-                    for (int i = 0; i < tuning.length; i++)
-                        tuning[i] = i * 100 + octave_tuning[i % 12];
-                    break;
-                }
-                case 0x07: // SINGLE NOTE TUNING CHANGE (NON
-                           // REAL-TIME/REAL-TIME) (BANK)
-                    // http://www.midi.org/about-midi/tuning_extens.shtml
-                    int ll = data[7] & 0xFF;
-                    int r = 8;
-                    for (int i = 0; i < ll; i++) {
-                        int kk = data[r++] & 0xFF;
-                        int xx = data[r++] & 0xFF;
-                        int yy = data[r++] & 0xFF;
-                        int zz = data[r++] & 0xFF;
-                        if (!(xx == 127 && yy == 127 && zz == 127))
-                            tuning[kk] = 100.0
-                                    * (((xx*16384) + (yy*128) + zz) / 16384.0);
-                    }
-                    break;
-                case 0x08: // scale/octave tuning 1-byte form (Non
-                           // Real-Time/REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning-scale.shtml
-                    int[] octave_tuning = new int[12];
-                    for (int i = 0; i < 12; i++)
-                        octave_tuning[i] = (data[i + 8] & 0xFF) - 64;
-                    for (int i = 0; i < tuning.length; i++)
-                        tuning[i] = i * 100 + octave_tuning[i % 12];
-                    break;
-                }
-                case 0x09: // scale/octave tuning 2-byte form (Non
-                           // Real-Time/REAL-TIME)
-                {
-                    // http://www.midi.org/about-midi/tuning-scale.shtml
-                    double[] octave_tuning = new double[12];
-                    for (int i = 0; i < 12; i++) {
-                        int v = (data[i * 2 + 8] & 0xFF) * 128
-                                + (data[i * 2 + 9] & 0xFF);
-                        octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
-                    }
-                    for (int i = 0; i < tuning.length; i++)
-                        tuning[i] = i * 100 + octave_tuning[i % 12];
-                    break;
-                }
-                default:
-                    break;
-                }
-            }
-        }
-    }
-
-    public double[] getTuning() {
-        return tuning;
-    }
-
-    public double getTuning(int noteNumber) {
-        return tuning[noteNumber];
-    }
-
-    public Patch getPatch() {
-        return patch;
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.UnsupportedEncodingException;
+
+import javax.sound.midi.Patch;
+
+/**
+ * A tuning program container, for use with MIDI Tuning.
+ * See: http://www.midi.org
+ *
+ * @author Karl Helgason
+ */
+public class SoftTuning {
+
+    private String name = null;
+    private double[] tuning = new double[128];
+    private Patch patch = null;
+
+    public SoftTuning() {
+        name = "12-TET";
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+    }
+
+    public SoftTuning(byte[] data) {
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+        load(data);
+    }
+
+    public SoftTuning(Patch patch) {
+        this.patch = patch;
+        name = "12-TET";
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+    }
+
+    public SoftTuning(Patch patch, byte[] data) {
+        this.patch = patch;
+        for (int i = 0; i < tuning.length; i++)
+            tuning[i] = i * 100;
+        load(data);
+    }
+
+    private boolean checksumOK(byte[] data) {
+        int x = data[1] & 0xFF;
+        for (int i = 2; i < data.length - 2; i++)
+            x = x ^ (data[i] & 0xFF);
+        return (data[data.length - 2] & 0xFF) == (x & 127);
+    }
+
+    /*
+    private boolean checksumOK2(byte[] data) {
+        int x = data[1] & 0xFF; // 7E
+        x = x ^ (data[2] & 0xFF); // <device ID>
+        x = x ^ (data[4] & 0xFF); // nn
+        x = x ^ (data[5] & 0xFF); // tt
+        for (int i = 22; i < data.length - 2; i++)
+            x = x ^ (data[i] & 0xFF);
+        return (data[data.length - 2] & 0xFF) == (x & 127);
+    }
+     */
+    public void load(byte[] data) {
+        // Universal Non-Real-Time / Real-Time SysEx
+        if ((data[1] & 0xFF) == 0x7E || (data[1] & 0xFF) == 0x7F) {
+            int subid1 = data[3] & 0xFF;
+            switch (subid1) {
+            case 0x08: // MIDI Tuning Standard
+                int subid2 = data[4] & 0xFF;
+                switch (subid2) {
+                case 0x01: // BULK TUNING DUMP (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning.shtml
+                    //if (!checksumOK2(data))
+                    //  break;
+                    try {
+                        name = new String(data, 6, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    int r = 22;
+                    for (int i = 0; i < 128; i++) {
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[i] = 100.0 *
+                                    (((xx * 16384) + (yy * 128) + zz) / 16384.0);
+                    }
+                    break;
+                }
+                case 0x02: // SINGLE NOTE TUNING CHANGE (REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning.shtml
+                    int ll = data[6] & 0xFF;
+                    int r = 7;
+                    for (int i = 0; i < ll; i++) {
+                        int kk = data[r++] & 0xFF;
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[kk] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
+                    }
+                    break;
+                }
+                case 0x04: // KEY-BASED TUNING DUMP (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    if (!checksumOK(data))
+                        break;
+                    try {
+                        name = new String(data, 7, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    int r = 23;
+                    for (int i = 0; i < 128; i++) {
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[i] = 100.0*(((xx*16384) + (yy*128) + zz)/16384.0);
+                    }
+                    break;
+                }
+                case 0x05: // SCALE/OCTAVE TUNING DUMP, 1 byte format
+                           // (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    if (!checksumOK(data))
+                        break;
+                    try {
+                        name = new String(data, 7, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    int[] octave_tuning = new int[12];
+                    for (int i = 0; i < 12; i++)
+                        octave_tuning[i] = (data[i + 23] & 0xFF) - 64;
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                case 0x06: // SCALE/OCTAVE TUNING DUMP, 2 byte format
+                           // (NON-REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    if (!checksumOK(data))
+                        break;
+                    try {
+                        name = new String(data, 7, 16, "ascii");
+                    } catch (UnsupportedEncodingException e) {
+                        name = null;
+                    }
+                    double[] octave_tuning = new double[12];
+                    for (int i = 0; i < 12; i++) {
+                        int v = (data[i * 2 + 23] & 0xFF) * 128
+                                + (data[i * 2 + 24] & 0xFF);
+                        octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
+                    }
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                case 0x07: // SINGLE NOTE TUNING CHANGE (NON
+                           // REAL-TIME/REAL-TIME) (BANK)
+                    // http://www.midi.org/about-midi/tuning_extens.shtml
+                    int ll = data[7] & 0xFF;
+                    int r = 8;
+                    for (int i = 0; i < ll; i++) {
+                        int kk = data[r++] & 0xFF;
+                        int xx = data[r++] & 0xFF;
+                        int yy = data[r++] & 0xFF;
+                        int zz = data[r++] & 0xFF;
+                        if (!(xx == 127 && yy == 127 && zz == 127))
+                            tuning[kk] = 100.0
+                                    * (((xx*16384) + (yy*128) + zz) / 16384.0);
+                    }
+                    break;
+                case 0x08: // scale/octave tuning 1-byte form (Non
+                           // Real-Time/REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning-scale.shtml
+                    int[] octave_tuning = new int[12];
+                    for (int i = 0; i < 12; i++)
+                        octave_tuning[i] = (data[i + 8] & 0xFF) - 64;
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                case 0x09: // scale/octave tuning 2-byte form (Non
+                           // Real-Time/REAL-TIME)
+                {
+                    // http://www.midi.org/about-midi/tuning-scale.shtml
+                    double[] octave_tuning = new double[12];
+                    for (int i = 0; i < 12; i++) {
+                        int v = (data[i * 2 + 8] & 0xFF) * 128
+                                + (data[i * 2 + 9] & 0xFF);
+                        octave_tuning[i] = (v / 8192.0 - 1) * 100.0;
+                    }
+                    for (int i = 0; i < tuning.length; i++)
+                        tuning[i] = i * 100 + octave_tuning[i % 12];
+                    break;
+                }
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
+    public double[] getTuning() {
+        return tuning;
+    }
+
+    public double getTuning(int noteNumber) {
+        return tuning[noteNumber];
+    }
+
+    public Patch getPatch() {
+        return patch;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/SoftVoice.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,841 +1,841 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.sound.midi.VoiceStatus;
-
-/**
- * Software synthesizer voice class.
- *
- * @author Karl Helgason
- */
-public class SoftVoice extends VoiceStatus {
-
-    public int exclusiveClass = 0;
-    public boolean releaseTriggered = false;
-    private int noteOn_noteNumber = 0;
-    private int noteOn_velocity = 0;
-    private int noteOff_velocity = 0;
-    protected ModelChannelMixer channelmixer = null;
-    protected double tunedKey = 0;
-    protected SoftTuning tuning = null;
-    protected SoftChannel stealer_channel = null;
-    protected ModelConnectionBlock[] stealer_extendedConnectionBlocks = null;
-    protected SoftPerformer stealer_performer = null;
-    protected ModelChannelMixer stealer_channelmixer = null;
-    protected int stealer_voiceID = -1;
-    protected int stealer_noteNumber = 0;
-    protected int stealer_velocity = 0;
-    protected boolean stealer_releaseTriggered = false;
-    protected int voiceID = -1;
-    protected boolean sustain = false;
-    protected boolean sostenuto = false;
-    protected boolean portamento = false;
-    private SoftFilter filter_left;
-    private SoftFilter filter_right;
-    private SoftProcess eg = new SoftEnvelopeGenerator();
-    private SoftProcess lfo = new SoftLowFrequencyOscillator();
-    protected Map<String, SoftControl> objects =
-            new HashMap<String, SoftControl>();
-    protected SoftSynthesizer synthesizer;
-    protected SoftInstrument instrument;
-    protected SoftPerformer performer;
-    protected SoftChannel softchannel = null;
-    protected boolean on = false;
-    private boolean audiostarted = false;
-    private boolean started = false;
-    private boolean stopping = false;
-    private float osc_attenuation = 0.0f;
-    private ModelOscillatorStream osc_stream;
-    private int osc_stream_nrofchannels;
-    private float[][] osc_buff = new float[2][];
-    private boolean osc_stream_off_transmitted = false;
-    private boolean out_mixer_end = false;
-    private float out_mixer_left = 0;
-    private float out_mixer_right = 0;
-    private float out_mixer_effect1 = 0;
-    private float out_mixer_effect2 = 0;
-    private float last_out_mixer_left = 0;
-    private float last_out_mixer_right = 0;
-    private float last_out_mixer_effect1 = 0;
-    private float last_out_mixer_effect2 = 0;
-    protected ModelConnectionBlock[] extendedConnectionBlocks = null;
-    private ModelConnectionBlock[] connections;
-    // Last value added to destination
-    private double[] connections_last = new double[50];
-    // Pointer to source value
-    private double[][][] connections_src = new double[50][3][];
-    // Key-based override (if any)
-    private int[][] connections_src_kc = new int[50][3];
-    // Pointer to destination value
-    private double[][] connections_dst = new double[50][];
-    private boolean soundoff = false;
-    private float lastMuteValue = 0;
-    private float lastSoloMuteValue = 0;
-    protected double[] co_noteon_keynumber = new double[1];
-    protected double[] co_noteon_velocity = new double[1];
-    protected double[] co_noteon_on = new double[1];
-    private SoftControl co_noteon = new SoftControl() {
-        double[] keynumber = co_noteon_keynumber;
-        double[] velocity = co_noteon_velocity;
-        double[] on = co_noteon_on;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            if (name.equals("keynumber"))
-                return keynumber;
-            if (name.equals("velocity"))
-                return velocity;
-            if (name.equals("on"))
-                return on;
-            return null;
-        }
-    };
-    private double[] co_mixer_active = new double[1];
-    private double[] co_mixer_gain = new double[1];
-    private double[] co_mixer_pan = new double[1];
-    private double[] co_mixer_balance = new double[1];
-    private double[] co_mixer_reverb = new double[1];
-    private double[] co_mixer_chorus = new double[1];
-    private SoftControl co_mixer = new SoftControl() {
-        double[] active = co_mixer_active;
-        double[] gain = co_mixer_gain;
-        double[] pan = co_mixer_pan;
-        double[] balance = co_mixer_balance;
-        double[] reverb = co_mixer_reverb;
-        double[] chorus = co_mixer_chorus;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            if (name.equals("active"))
-                return active;
-            if (name.equals("gain"))
-                return gain;
-            if (name.equals("pan"))
-                return pan;
-            if (name.equals("balance"))
-                return balance;
-            if (name.equals("reverb"))
-                return reverb;
-            if (name.equals("chorus"))
-                return chorus;
-            return null;
-        }
-    };
-    private double[] co_osc_pitch = new double[1];
-    private SoftControl co_osc = new SoftControl() {
-        double[] pitch = co_osc_pitch;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            if (name.equals("pitch"))
-                return pitch;
-            return null;
-        }
-    };
-    private double[] co_filter_freq = new double[1];
-    private double[] co_filter_type = new double[1];
-    private double[] co_filter_q = new double[1];
-    private SoftControl co_filter = new SoftControl() {
-        double[] freq = co_filter_freq;
-        double[] ftype = co_filter_type;
-        double[] q = co_filter_q;
-        public double[] get(int instance, String name) {
-            if (name == null)
-                return null;
-            if (name.equals("freq"))
-                return freq;
-            if (name.equals("type"))
-                return ftype;
-            if (name.equals("q"))
-                return q;
-            return null;
-        }
-    };
-    protected SoftResamplerStreamer resampler;
-    private int nrofchannels;
-
-    public SoftVoice(SoftSynthesizer synth) {
-        synthesizer = synth;
-        filter_left = new SoftFilter(synth.getFormat().getSampleRate());
-        filter_right = new SoftFilter(synth.getFormat().getSampleRate());
-        nrofchannels = synth.getFormat().getChannels();
-    }
-
-    private int getValueKC(ModelIdentifier id) {
-        if (id.getObject().equals("midi_cc")) {
-            int ic = Integer.parseInt(id.getVariable());
-            if (ic != 0 && ic != 32) {
-                if (ic < 120)
-                    return ic;
-            }
-        } else if (id.getObject().equals("midi_rpn")) {
-            if (id.getVariable().equals("1"))
-                return 120; // Fine tuning
-            if (id.getVariable().equals("2"))
-                return 121; // Coarse tuning
-        }
-        return -1;
-    }
-
-    private double[] getValue(ModelIdentifier id) {
-        SoftControl o = objects.get(id.getObject());
-        if (o == null)
-            return null;
-        return o.get(id.getInstance(), id.getVariable());
-    }
-
-    private double transformValue(double value, ModelSource src) {
-        if (src.getTransform() != null)
-            return src.getTransform().transform(value);
-        else
-            return value;
-    }
-
-    private double transformValue(double value, ModelDestination dst) {
-        if (dst.getTransform() != null)
-            return dst.getTransform().transform(value);
-        else
-            return value;
-    }
-
-    private double processKeyBasedController(double value, int keycontrol) {
-        if (keycontrol == -1)
-            return value;
-        if (softchannel.keybasedcontroller_active != null)
-            if (softchannel.keybasedcontroller_active[note] != null)
-                if (softchannel.keybasedcontroller_active[note][keycontrol]) {
-                    double key_controlvalue =
-                            softchannel.keybasedcontroller_value[note][keycontrol];
-                    if (keycontrol == 10 || keycontrol == 91 || keycontrol == 93)
-                        return key_controlvalue;
-                    value += key_controlvalue * 2.0 - 1.0;
-                    if (value > 1)
-                        value = 1;
-                    else if (value < 0)
-                        value = 0;
-                }
-        return value;
-    }
-
-    private void processConnection(int ix) {
-        ModelConnectionBlock conn = connections[ix];
-        double[][] src = connections_src[ix];
-        double[] dst = connections_dst[ix];
-        if (dst == null || Double.isInfinite(dst[0]))
-            return;
-
-        double value = conn.getScale();
-        if (softchannel.keybasedcontroller_active == null) {
-            ModelSource[] srcs = conn.getSources();
-            for (int i = 0; i < srcs.length; i++) {
-                value *= transformValue(src[i][0], srcs[i]);
-                if (value == 0)
-                    break;
-            }
-        } else {
-            ModelSource[] srcs = conn.getSources();
-            int[] src_kc = connections_src_kc[ix];
-            for (int i = 0; i < srcs.length; i++) {
-                value *= transformValue(processKeyBasedController(src[i][0],
-                        src_kc[i]), srcs[i]);
-                if (value == 0)
-                    break;
-            }
-        }
-
-        value = transformValue(value, conn.getDestination());
-        dst[0] = dst[0] - connections_last[ix] + value;
-        connections_last[ix] = value;
-        // co_mixer_gain[0] = 0;
-    }
-
-    protected void updateTuning(SoftTuning newtuning) {
-        tunedKey = tuning.getTuning(note) / 100.0;
-        if (!portamento) {
-            co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
-            int[] c = performer.midi_connections[4];
-            if (c == null)
-                return;
-            for (int i = 0; i < c.length; i++)
-                processConnection(c[i]);
-        }
-    }
-
-    protected void setNote(int noteNumber) {
-        note = noteNumber;
-        tunedKey = tuning.getTuning(noteNumber) / 100.0;
-    }
-
-    protected void noteOn(int noteNumber, int velocity) {
-
-        sustain = false;
-        sostenuto = false;
-        portamento = false;
-
-        soundoff = false;
-        on = true;
-        active = true;
-        started = true;
-        // volume = velocity;
-
-        noteOn_noteNumber = noteNumber;
-        noteOn_velocity = velocity;
-
-        lastMuteValue = 0;
-        lastSoloMuteValue = 0;
-
-        setNote(noteNumber);
-
-        if (performer.forcedKeynumber)
-            co_noteon_keynumber[0] = 0;
-        else
-            co_noteon_keynumber[0] = tunedKey * (1f / 128f);
-        if (performer.forcedVelocity)
-            co_noteon_velocity[0] = 0;
-        else
-            co_noteon_velocity[0] = velocity * (1f / 128f);
-        co_mixer_active[0] = 0;
-        co_mixer_gain[0] = 0;
-        co_mixer_pan[0] = 0;
-        co_mixer_balance[0] = 0;
-        co_mixer_reverb[0] = 0;
-        co_mixer_chorus[0] = 0;
-        co_osc_pitch[0] = 0;
-        co_filter_freq[0] = 0;
-        co_filter_q[0] = 0;
-        co_filter_type[0] = 0;
-        co_noteon_on[0] = 1;
-
-        eg.reset();
-        lfo.reset();
-        filter_left.reset();
-        filter_right.reset();
-
-        objects.put("master", synthesizer.getMainMixer().co_master);
-        objects.put("eg", eg);
-        objects.put("lfo", lfo);
-        objects.put("noteon", co_noteon);
-        objects.put("osc", co_osc);
-        objects.put("mixer", co_mixer);
-        objects.put("filter", co_filter);
-
-        connections = performer.connections;
-
-        if (connections_last == null
-                || connections_last.length < connections.length) {
-            connections_last = new double[connections.length];
-        }
-        if (connections_src == null
-                || connections_src.length < connections.length) {
-            connections_src = new double[connections.length][][];
-            connections_src_kc = new int[connections.length][];
-        }
-        if (connections_dst == null
-                || connections_dst.length < connections.length) {
-            connections_dst = new double[connections.length][];
-        }
-        for (int i = 0; i < connections.length; i++) {
-            ModelConnectionBlock conn = connections[i];
-            connections_last[i] = 0;
-            if (conn.getSources() != null) {
-                ModelSource[] srcs = conn.getSources();
-                if (connections_src[i] == null
-                        || connections_src[i].length < srcs.length) {
-                    connections_src[i] = new double[srcs.length][];
-                    connections_src_kc[i] = new int[srcs.length];
-                }
-                double[][] src = connections_src[i];
-                int[] src_kc = connections_src_kc[i];
-                connections_src[i] = src;
-                for (int j = 0; j < srcs.length; j++) {
-                    src_kc[j] = getValueKC(srcs[j].getIdentifier());
-                    src[j] = getValue(srcs[j].getIdentifier());
-                }
-            }
-
-            if (conn.getDestination() != null)
-                connections_dst[i] = getValue(conn.getDestination()
-                        .getIdentifier());
-            else
-                connections_dst[i] = null;
-        }
-
-        for (int i = 0; i < connections.length; i++)
-            processConnection(i);
-
-        if (extendedConnectionBlocks != null) {
-            for (ModelConnectionBlock connection: extendedConnectionBlocks) {
-                double value = 0;
-
-                if (softchannel.keybasedcontroller_active == null) {
-                    for (ModelSource src: connection.getSources()) {
-                        double x = getValue(src.getIdentifier())[0];
-                        ModelTransform t = src.getTransform();
-                        if (t == null)
-                            value += x;
-                        else
-                            value += t.transform(x);
-                    }
-                } else {
-                    for (ModelSource src: connection.getSources()) {
-                        double x = getValue(src.getIdentifier())[0];
-                        x = processKeyBasedController(x,
-                                getValueKC(src.getIdentifier()));
-                        ModelTransform t = src.getTransform();
-                        if (t == null)
-                            value += x;
-                        else
-                            value += t.transform(x);
-                    }
-                }
-
-                ModelDestination dest = connection.getDestination();
-                ModelTransform t = dest.getTransform();
-                if (t != null)
-                    value = t.transform(value);
-                getValue(dest.getIdentifier())[0] += value;
-            }
-        }
-
-        eg.init(synthesizer);
-        lfo.init(synthesizer);
-
-    }
-
-    protected void setPolyPressure(int pressure) {
-        int[] c = performer.midi_connections[2];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void setChannelPressure(int pressure) {
-        int[] c = performer.midi_connections[1];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void controlChange(int controller, int value) {
-        int[] c = performer.midi_ctrl_connections[controller];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void nrpnChange(int controller, int value) {
-        int[] c = performer.midi_nrpn_connections.get(controller);
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void rpnChange(int controller, int value) {
-        int[] c = performer.midi_rpn_connections.get(controller);
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void setPitchBend(int bend) {
-        int[] c = performer.midi_connections[0];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void setMute(boolean mute) {
-        co_mixer_gain[0] -= lastMuteValue;
-        lastMuteValue = mute ? -960 : 0;
-        co_mixer_gain[0] += lastMuteValue;
-    }
-
-    protected void setSoloMute(boolean mute) {
-        co_mixer_gain[0] -= lastSoloMuteValue;
-        lastSoloMuteValue = mute ? -960 : 0;
-        co_mixer_gain[0] += lastSoloMuteValue;
-    }
-
-    protected void shutdown() {
-        if (co_noteon_on[0] < -0.5)
-            return;
-        on = false;
-
-        co_noteon_on[0] = -1;
-
-        int[] c = performer.midi_connections[3];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void soundOff() {
-        on = false;
-        soundoff = true;
-    }
-
-    protected void noteOff(int velocity) {
-        if (!on)
-            return;
-        on = false;
-
-        noteOff_velocity = velocity;
-
-        if (softchannel.sustain) {
-            sustain = true;
-            return;
-        }
-        if (sostenuto)
-            return;
-
-        co_noteon_on[0] = 0;
-
-        int[] c = performer.midi_connections[3];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void redamp() {
-        if (co_noteon_on[0] > 0.5)
-            return;
-        if (co_noteon_on[0] < -0.5)
-            return; // don't redamp notes in shutdown stage
-
-        sustain = true;
-        co_noteon_on[0] = 1;
-
-        int[] c = performer.midi_connections[3];
-        if (c == null)
-            return;
-        for (int i = 0; i < c.length; i++)
-            processConnection(c[i]);
-    }
-
-    protected void processControlLogic() {
-        if (stopping) {
-            active = false;
-            stopping = false;
-            audiostarted = false;
-            if (osc_stream != null)
-                try {
-                    osc_stream.close();
-                } catch (IOException e) {
-                    //e.printStackTrace();
-                }
-
-            if (stealer_channel != null) {
-                stealer_channel.initVoice(this, stealer_performer,
-                        stealer_voiceID, stealer_noteNumber, stealer_velocity,
-                        stealer_extendedConnectionBlocks, stealer_channelmixer,
-                        stealer_releaseTriggered);
-                stealer_releaseTriggered = false;
-                stealer_channel = null;
-                stealer_performer = null;
-                stealer_voiceID = -1;
-                stealer_noteNumber = 0;
-                stealer_velocity = 0;
-                stealer_extendedConnectionBlocks = null;
-                stealer_channelmixer = null;
-            }
-        }
-        if (started) {
-            audiostarted = true;
-
-            ModelOscillator osc = performer.oscillators[0];
-
-            osc_stream_off_transmitted = false;
-            if (osc instanceof ModelWavetable) {
-                try {
-                    resampler.open((ModelWavetable)osc,
-                            synthesizer.getFormat().getSampleRate());
-                    osc_stream = resampler;
-                } catch (IOException e) {
-                    //e.printStackTrace();
-                }
-            } else {
-                osc_stream = osc.open(synthesizer.getFormat().getSampleRate());
-            }
-            osc_attenuation = osc.getAttenuation();
-            osc_stream_nrofchannels = osc.getChannels();
-            if (osc_buff == null || osc_buff.length < osc_stream_nrofchannels)
-                osc_buff = new float[osc_stream_nrofchannels][];
-
-            if (osc_stream != null)
-                osc_stream.noteOn(softchannel, this, noteOn_noteNumber,
-                        noteOn_velocity);
-
-
-        }
-        if (audiostarted) {
-            if (portamento) {
-                double note_delta = tunedKey - (co_noteon_keynumber[0] * 128);
-                double note_delta_a = Math.abs(note_delta);
-                if (note_delta_a < 0.0000000001) {
-                    co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
-                    portamento = false;
-                } else {
-                    if (note_delta_a > softchannel.portamento_time)
-                        note_delta = Math.signum(note_delta)
-                                * softchannel.portamento_time;
-                    co_noteon_keynumber[0] += note_delta * (1.0 / 128.0);
-                }
-
-                int[] c = performer.midi_connections[4];
-                if (c == null)
-                    return;
-                for (int i = 0; i < c.length; i++)
-                    processConnection(c[i]);
-            }
-
-            eg.processControlLogic();
-            lfo.processControlLogic();
-
-            for (int i = 0; i < performer.ctrl_connections.length; i++)
-                processConnection(performer.ctrl_connections[i]);
-
-            osc_stream.setPitch((float)co_osc_pitch[0]);
-
-            int filter_type = (int)co_filter_type[0];
-            double filter_freq;
-
-            if (co_filter_freq[0] == 13500.0)
-                filter_freq = 19912.126958213175;
-            else
-                filter_freq = 440.0 * Math.exp(
-                        ((co_filter_freq[0]) - 6900.0) *
-                        (Math.log(2.0) / 1200.0));
-            /*
-            filter_freq = 440.0 * Math.pow(2.0,
-            ((co_filter_freq[0]) - 6900.0) / 1200.0);*/
-            /*
-             * double velocity = co_noteon_velocity[0]; if(velocity < 0.5)
-             * filter_freq *= ((velocity * 2)*0.75 + 0.25);
-             */
-
-            double q = co_filter_q[0] / 10.0;
-            filter_left.setFilterType(filter_type);
-            filter_left.setFrequency(filter_freq);
-            filter_left.setResonance(q);
-            filter_right.setFilterType(filter_type);
-            filter_right.setFrequency(filter_freq);
-            filter_right.setResonance(q);
-            /*
-            float gain = (float) Math.pow(10,
-            (-osc_attenuation + co_mixer_gain[0]) / 200.0);
-             */
-            float gain = (float)Math.exp(
-                    (-osc_attenuation + co_mixer_gain[0])*(Math.log(10) / 200.0));
-
-            if (co_mixer_gain[0] <= -960)
-                gain = 0;
-
-            if (soundoff) {
-                stopping = true;
-                gain = 0;
-                /*
-                 * if(co_mixer_gain[0] > -960)
-                 *   co_mixer_gain[0] -= 960;
-                 */
-            }
-
-            volume = (int)(Math.sqrt(gain) * 128);
-
-            // gain *= 0.2;
-
-            double pan = co_mixer_pan[0] * (1.0 / 1000.0);
-            // System.out.println("pan = " + pan);
-            if (pan < 0)
-                pan = 0;
-            else if (pan > 1)
-                pan = 1;
-
-            if (pan == 0.5) {
-                out_mixer_left = gain * 0.7071067811865476f;
-                out_mixer_right = out_mixer_left;
-            } else {
-                out_mixer_left = gain * (float)Math.cos(pan * Math.PI * 0.5);
-                out_mixer_right = gain * (float)Math.sin(pan * Math.PI * 0.5);
-            }
-
-            double balance = co_mixer_balance[0] * (1.0 / 1000.0);
-            if (balance != 0.5) {
-                if (balance > 0.5)
-                    out_mixer_left *= (1 - balance) * 2;
-                else
-                    out_mixer_right *= balance * 2;
-            }
-
-            if (synthesizer.reverb_on) {
-                out_mixer_effect1 = (float)(co_mixer_reverb[0] * (1.0 / 1000.0));
-                out_mixer_effect1 *= gain;
-            } else
-                out_mixer_effect1 = 0;
-            if (synthesizer.chorus_on) {
-                out_mixer_effect2 = (float)(co_mixer_chorus[0] * (1.0 / 1000.0));
-                out_mixer_effect2 *= gain;
-            } else
-                out_mixer_effect2 = 0;
-            out_mixer_end = co_mixer_active[0] < 0.5;
-
-            if (!on)
-                if (!osc_stream_off_transmitted) {
-                    osc_stream_off_transmitted = true;
-                    if (osc_stream != null)
-                        osc_stream.noteOff(noteOff_velocity);
-                }
-
-        }
-        if (started) {
-            last_out_mixer_left = out_mixer_left;
-            last_out_mixer_right = out_mixer_right;
-            last_out_mixer_effect1 = out_mixer_effect1;
-            last_out_mixer_effect2 = out_mixer_effect2;
-            started = false;
-        }
-
-    }
-
-    protected void mixAudioStream(SoftAudioBuffer in, SoftAudioBuffer out,
-            float amp_from, float amp_to) {
-        int bufferlen = in.getSize();
-        if (amp_from < 0.000000001 && amp_to < 0.000000001)
-            return;
-        if (amp_from == amp_to) {
-            float[] fout = out.array();
-            float[] fin = in.array();
-            for (int i = 0; i < bufferlen; i++)
-                fout[i] += fin[i] * amp_to;
-        } else {
-            float amp = amp_from;
-            float amp_delta = (amp_to - amp_from) / bufferlen;
-            float[] fout = out.array();
-            float[] fin = in.array();
-            for (int i = 0; i < bufferlen; i++) {
-                amp += amp_delta;
-                fout[i] += fin[i] * amp;
-            }
-        }
-
-    }
-
-    protected void processAudioLogic(SoftAudioBuffer[] buffer) {
-        if (!audiostarted)
-            return;
-
-        int bufferlen = buffer[0].getSize();
-
-        try {
-            osc_buff[0] = buffer[SoftMainMixer.CHANNEL_LEFT_DRY].array();
-            if (nrofchannels != 1)
-                osc_buff[1] = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY].array();
-            int ret = osc_stream.read(osc_buff, 0, bufferlen);
-            if (ret == -1) {
-                stopping = true;
-                return;
-            }
-            if (ret != bufferlen) {
-                Arrays.fill(osc_buff[0], ret, bufferlen, 0f);
-                if (nrofchannels != 1)
-                    Arrays.fill(osc_buff[1], ret, bufferlen, 0f);
-            }
-
-        } catch (IOException e) {
-            //e.printStackTrace();
-        }
-
-        SoftAudioBuffer left = buffer[SoftMainMixer.CHANNEL_LEFT];
-        SoftAudioBuffer right = buffer[SoftMainMixer.CHANNEL_RIGHT];
-        SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1];
-        SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2];
-        SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY];
-        SoftAudioBuffer rightdry = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY];
-
-        if (osc_stream_nrofchannels == 1)
-            rightdry = null;
-
-        if (!Double.isInfinite(co_filter_freq[0])) {
-            filter_left.processAudio(leftdry);
-            if (rightdry != null)
-                filter_right.processAudio(rightdry);
-        }
-
-        if (nrofchannels == 1) {
-            out_mixer_left = (out_mixer_left + out_mixer_right) / 2;
-            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
-            if (rightdry != null)
-                mixAudioStream(rightdry, left, last_out_mixer_left,
-                        out_mixer_left);
-        } else {
-            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
-            if (rightdry != null)
-                mixAudioStream(rightdry, right, last_out_mixer_right,
-                        out_mixer_right);
-            else
-                mixAudioStream(leftdry, right, last_out_mixer_right,
-                        out_mixer_right);
-        }
-
-        if (rightdry == null) {
-            mixAudioStream(leftdry, eff1, last_out_mixer_effect1,
-                    out_mixer_effect1);
-            mixAudioStream(leftdry, eff2, last_out_mixer_effect2,
-                    out_mixer_effect2);
-        } else {
-            mixAudioStream(leftdry, eff1, last_out_mixer_effect1 * 0.5f,
-                    out_mixer_effect1 * 0.5f);
-            mixAudioStream(leftdry, eff2, last_out_mixer_effect2 * 0.5f,
-                    out_mixer_effect2 * 0.5f);
-            mixAudioStream(rightdry, eff1, last_out_mixer_effect1 * 0.5f,
-                    out_mixer_effect1 * 0.5f);
-            mixAudioStream(rightdry, eff2, last_out_mixer_effect2 * 0.5f,
-                    out_mixer_effect2 * 0.5f);
-        }
-
-        last_out_mixer_left = out_mixer_left;
-        last_out_mixer_right = out_mixer_right;
-        last_out_mixer_effect1 = out_mixer_effect1;
-        last_out_mixer_effect2 = out_mixer_effect2;
-
-        if (out_mixer_end) {
-            stopping = true;
-        }
-
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.sound.midi.VoiceStatus;
+
+/**
+ * Software synthesizer voice class.
+ *
+ * @author Karl Helgason
+ */
+public class SoftVoice extends VoiceStatus {
+
+    public int exclusiveClass = 0;
+    public boolean releaseTriggered = false;
+    private int noteOn_noteNumber = 0;
+    private int noteOn_velocity = 0;
+    private int noteOff_velocity = 0;
+    protected ModelChannelMixer channelmixer = null;
+    protected double tunedKey = 0;
+    protected SoftTuning tuning = null;
+    protected SoftChannel stealer_channel = null;
+    protected ModelConnectionBlock[] stealer_extendedConnectionBlocks = null;
+    protected SoftPerformer stealer_performer = null;
+    protected ModelChannelMixer stealer_channelmixer = null;
+    protected int stealer_voiceID = -1;
+    protected int stealer_noteNumber = 0;
+    protected int stealer_velocity = 0;
+    protected boolean stealer_releaseTriggered = false;
+    protected int voiceID = -1;
+    protected boolean sustain = false;
+    protected boolean sostenuto = false;
+    protected boolean portamento = false;
+    private SoftFilter filter_left;
+    private SoftFilter filter_right;
+    private SoftProcess eg = new SoftEnvelopeGenerator();
+    private SoftProcess lfo = new SoftLowFrequencyOscillator();
+    protected Map<String, SoftControl> objects =
+            new HashMap<String, SoftControl>();
+    protected SoftSynthesizer synthesizer;
+    protected SoftInstrument instrument;
+    protected SoftPerformer performer;
+    protected SoftChannel softchannel = null;
+    protected boolean on = false;
+    private boolean audiostarted = false;
+    private boolean started = false;
+    private boolean stopping = false;
+    private float osc_attenuation = 0.0f;
+    private ModelOscillatorStream osc_stream;
+    private int osc_stream_nrofchannels;
+    private float[][] osc_buff = new float[2][];
+    private boolean osc_stream_off_transmitted = false;
+    private boolean out_mixer_end = false;
+    private float out_mixer_left = 0;
+    private float out_mixer_right = 0;
+    private float out_mixer_effect1 = 0;
+    private float out_mixer_effect2 = 0;
+    private float last_out_mixer_left = 0;
+    private float last_out_mixer_right = 0;
+    private float last_out_mixer_effect1 = 0;
+    private float last_out_mixer_effect2 = 0;
+    protected ModelConnectionBlock[] extendedConnectionBlocks = null;
+    private ModelConnectionBlock[] connections;
+    // Last value added to destination
+    private double[] connections_last = new double[50];
+    // Pointer to source value
+    private double[][][] connections_src = new double[50][3][];
+    // Key-based override (if any)
+    private int[][] connections_src_kc = new int[50][3];
+    // Pointer to destination value
+    private double[][] connections_dst = new double[50][];
+    private boolean soundoff = false;
+    private float lastMuteValue = 0;
+    private float lastSoloMuteValue = 0;
+    protected double[] co_noteon_keynumber = new double[1];
+    protected double[] co_noteon_velocity = new double[1];
+    protected double[] co_noteon_on = new double[1];
+    private SoftControl co_noteon = new SoftControl() {
+        double[] keynumber = co_noteon_keynumber;
+        double[] velocity = co_noteon_velocity;
+        double[] on = co_noteon_on;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("keynumber"))
+                return keynumber;
+            if (name.equals("velocity"))
+                return velocity;
+            if (name.equals("on"))
+                return on;
+            return null;
+        }
+    };
+    private double[] co_mixer_active = new double[1];
+    private double[] co_mixer_gain = new double[1];
+    private double[] co_mixer_pan = new double[1];
+    private double[] co_mixer_balance = new double[1];
+    private double[] co_mixer_reverb = new double[1];
+    private double[] co_mixer_chorus = new double[1];
+    private SoftControl co_mixer = new SoftControl() {
+        double[] active = co_mixer_active;
+        double[] gain = co_mixer_gain;
+        double[] pan = co_mixer_pan;
+        double[] balance = co_mixer_balance;
+        double[] reverb = co_mixer_reverb;
+        double[] chorus = co_mixer_chorus;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("active"))
+                return active;
+            if (name.equals("gain"))
+                return gain;
+            if (name.equals("pan"))
+                return pan;
+            if (name.equals("balance"))
+                return balance;
+            if (name.equals("reverb"))
+                return reverb;
+            if (name.equals("chorus"))
+                return chorus;
+            return null;
+        }
+    };
+    private double[] co_osc_pitch = new double[1];
+    private SoftControl co_osc = new SoftControl() {
+        double[] pitch = co_osc_pitch;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("pitch"))
+                return pitch;
+            return null;
+        }
+    };
+    private double[] co_filter_freq = new double[1];
+    private double[] co_filter_type = new double[1];
+    private double[] co_filter_q = new double[1];
+    private SoftControl co_filter = new SoftControl() {
+        double[] freq = co_filter_freq;
+        double[] ftype = co_filter_type;
+        double[] q = co_filter_q;
+        public double[] get(int instance, String name) {
+            if (name == null)
+                return null;
+            if (name.equals("freq"))
+                return freq;
+            if (name.equals("type"))
+                return ftype;
+            if (name.equals("q"))
+                return q;
+            return null;
+        }
+    };
+    protected SoftResamplerStreamer resampler;
+    private int nrofchannels;
+
+    public SoftVoice(SoftSynthesizer synth) {
+        synthesizer = synth;
+        filter_left = new SoftFilter(synth.getFormat().getSampleRate());
+        filter_right = new SoftFilter(synth.getFormat().getSampleRate());
+        nrofchannels = synth.getFormat().getChannels();
+    }
+
+    private int getValueKC(ModelIdentifier id) {
+        if (id.getObject().equals("midi_cc")) {
+            int ic = Integer.parseInt(id.getVariable());
+            if (ic != 0 && ic != 32) {
+                if (ic < 120)
+                    return ic;
+            }
+        } else if (id.getObject().equals("midi_rpn")) {
+            if (id.getVariable().equals("1"))
+                return 120; // Fine tuning
+            if (id.getVariable().equals("2"))
+                return 121; // Coarse tuning
+        }
+        return -1;
+    }
+
+    private double[] getValue(ModelIdentifier id) {
+        SoftControl o = objects.get(id.getObject());
+        if (o == null)
+            return null;
+        return o.get(id.getInstance(), id.getVariable());
+    }
+
+    private double transformValue(double value, ModelSource src) {
+        if (src.getTransform() != null)
+            return src.getTransform().transform(value);
+        else
+            return value;
+    }
+
+    private double transformValue(double value, ModelDestination dst) {
+        if (dst.getTransform() != null)
+            return dst.getTransform().transform(value);
+        else
+            return value;
+    }
+
+    private double processKeyBasedController(double value, int keycontrol) {
+        if (keycontrol == -1)
+            return value;
+        if (softchannel.keybasedcontroller_active != null)
+            if (softchannel.keybasedcontroller_active[note] != null)
+                if (softchannel.keybasedcontroller_active[note][keycontrol]) {
+                    double key_controlvalue =
+                            softchannel.keybasedcontroller_value[note][keycontrol];
+                    if (keycontrol == 10 || keycontrol == 91 || keycontrol == 93)
+                        return key_controlvalue;
+                    value += key_controlvalue * 2.0 - 1.0;
+                    if (value > 1)
+                        value = 1;
+                    else if (value < 0)
+                        value = 0;
+                }
+        return value;
+    }
+
+    private void processConnection(int ix) {
+        ModelConnectionBlock conn = connections[ix];
+        double[][] src = connections_src[ix];
+        double[] dst = connections_dst[ix];
+        if (dst == null || Double.isInfinite(dst[0]))
+            return;
+
+        double value = conn.getScale();
+        if (softchannel.keybasedcontroller_active == null) {
+            ModelSource[] srcs = conn.getSources();
+            for (int i = 0; i < srcs.length; i++) {
+                value *= transformValue(src[i][0], srcs[i]);
+                if (value == 0)
+                    break;
+            }
+        } else {
+            ModelSource[] srcs = conn.getSources();
+            int[] src_kc = connections_src_kc[ix];
+            for (int i = 0; i < srcs.length; i++) {
+                value *= transformValue(processKeyBasedController(src[i][0],
+                        src_kc[i]), srcs[i]);
+                if (value == 0)
+                    break;
+            }
+        }
+
+        value = transformValue(value, conn.getDestination());
+        dst[0] = dst[0] - connections_last[ix] + value;
+        connections_last[ix] = value;
+        // co_mixer_gain[0] = 0;
+    }
+
+    protected void updateTuning(SoftTuning newtuning) {
+        tunedKey = tuning.getTuning(note) / 100.0;
+        if (!portamento) {
+            co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
+            int[] c = performer.midi_connections[4];
+            if (c == null)
+                return;
+            for (int i = 0; i < c.length; i++)
+                processConnection(c[i]);
+        }
+    }
+
+    protected void setNote(int noteNumber) {
+        note = noteNumber;
+        tunedKey = tuning.getTuning(noteNumber) / 100.0;
+    }
+
+    protected void noteOn(int noteNumber, int velocity) {
+
+        sustain = false;
+        sostenuto = false;
+        portamento = false;
+
+        soundoff = false;
+        on = true;
+        active = true;
+        started = true;
+        // volume = velocity;
+
+        noteOn_noteNumber = noteNumber;
+        noteOn_velocity = velocity;
+
+        lastMuteValue = 0;
+        lastSoloMuteValue = 0;
+
+        setNote(noteNumber);
+
+        if (performer.forcedKeynumber)
+            co_noteon_keynumber[0] = 0;
+        else
+            co_noteon_keynumber[0] = tunedKey * (1f / 128f);
+        if (performer.forcedVelocity)
+            co_noteon_velocity[0] = 0;
+        else
+            co_noteon_velocity[0] = velocity * (1f / 128f);
+        co_mixer_active[0] = 0;
+        co_mixer_gain[0] = 0;
+        co_mixer_pan[0] = 0;
+        co_mixer_balance[0] = 0;
+        co_mixer_reverb[0] = 0;
+        co_mixer_chorus[0] = 0;
+        co_osc_pitch[0] = 0;
+        co_filter_freq[0] = 0;
+        co_filter_q[0] = 0;
+        co_filter_type[0] = 0;
+        co_noteon_on[0] = 1;
+
+        eg.reset();
+        lfo.reset();
+        filter_left.reset();
+        filter_right.reset();
+
+        objects.put("master", synthesizer.getMainMixer().co_master);
+        objects.put("eg", eg);
+        objects.put("lfo", lfo);
+        objects.put("noteon", co_noteon);
+        objects.put("osc", co_osc);
+        objects.put("mixer", co_mixer);
+        objects.put("filter", co_filter);
+
+        connections = performer.connections;
+
+        if (connections_last == null
+                || connections_last.length < connections.length) {
+            connections_last = new double[connections.length];
+        }
+        if (connections_src == null
+                || connections_src.length < connections.length) {
+            connections_src = new double[connections.length][][];
+            connections_src_kc = new int[connections.length][];
+        }
+        if (connections_dst == null
+                || connections_dst.length < connections.length) {
+            connections_dst = new double[connections.length][];
+        }
+        for (int i = 0; i < connections.length; i++) {
+            ModelConnectionBlock conn = connections[i];
+            connections_last[i] = 0;
+            if (conn.getSources() != null) {
+                ModelSource[] srcs = conn.getSources();
+                if (connections_src[i] == null
+                        || connections_src[i].length < srcs.length) {
+                    connections_src[i] = new double[srcs.length][];
+                    connections_src_kc[i] = new int[srcs.length];
+                }
+                double[][] src = connections_src[i];
+                int[] src_kc = connections_src_kc[i];
+                connections_src[i] = src;
+                for (int j = 0; j < srcs.length; j++) {
+                    src_kc[j] = getValueKC(srcs[j].getIdentifier());
+                    src[j] = getValue(srcs[j].getIdentifier());
+                }
+            }
+
+            if (conn.getDestination() != null)
+                connections_dst[i] = getValue(conn.getDestination()
+                        .getIdentifier());
+            else
+                connections_dst[i] = null;
+        }
+
+        for (int i = 0; i < connections.length; i++)
+            processConnection(i);
+
+        if (extendedConnectionBlocks != null) {
+            for (ModelConnectionBlock connection: extendedConnectionBlocks) {
+                double value = 0;
+
+                if (softchannel.keybasedcontroller_active == null) {
+                    for (ModelSource src: connection.getSources()) {
+                        double x = getValue(src.getIdentifier())[0];
+                        ModelTransform t = src.getTransform();
+                        if (t == null)
+                            value += x;
+                        else
+                            value += t.transform(x);
+                    }
+                } else {
+                    for (ModelSource src: connection.getSources()) {
+                        double x = getValue(src.getIdentifier())[0];
+                        x = processKeyBasedController(x,
+                                getValueKC(src.getIdentifier()));
+                        ModelTransform t = src.getTransform();
+                        if (t == null)
+                            value += x;
+                        else
+                            value += t.transform(x);
+                    }
+                }
+
+                ModelDestination dest = connection.getDestination();
+                ModelTransform t = dest.getTransform();
+                if (t != null)
+                    value = t.transform(value);
+                getValue(dest.getIdentifier())[0] += value;
+            }
+        }
+
+        eg.init(synthesizer);
+        lfo.init(synthesizer);
+
+    }
+
+    protected void setPolyPressure(int pressure) {
+        int[] c = performer.midi_connections[2];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void setChannelPressure(int pressure) {
+        int[] c = performer.midi_connections[1];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void controlChange(int controller, int value) {
+        int[] c = performer.midi_ctrl_connections[controller];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void nrpnChange(int controller, int value) {
+        int[] c = performer.midi_nrpn_connections.get(controller);
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void rpnChange(int controller, int value) {
+        int[] c = performer.midi_rpn_connections.get(controller);
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void setPitchBend(int bend) {
+        int[] c = performer.midi_connections[0];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void setMute(boolean mute) {
+        co_mixer_gain[0] -= lastMuteValue;
+        lastMuteValue = mute ? -960 : 0;
+        co_mixer_gain[0] += lastMuteValue;
+    }
+
+    protected void setSoloMute(boolean mute) {
+        co_mixer_gain[0] -= lastSoloMuteValue;
+        lastSoloMuteValue = mute ? -960 : 0;
+        co_mixer_gain[0] += lastSoloMuteValue;
+    }
+
+    protected void shutdown() {
+        if (co_noteon_on[0] < -0.5)
+            return;
+        on = false;
+
+        co_noteon_on[0] = -1;
+
+        int[] c = performer.midi_connections[3];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void soundOff() {
+        on = false;
+        soundoff = true;
+    }
+
+    protected void noteOff(int velocity) {
+        if (!on)
+            return;
+        on = false;
+
+        noteOff_velocity = velocity;
+
+        if (softchannel.sustain) {
+            sustain = true;
+            return;
+        }
+        if (sostenuto)
+            return;
+
+        co_noteon_on[0] = 0;
+
+        int[] c = performer.midi_connections[3];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void redamp() {
+        if (co_noteon_on[0] > 0.5)
+            return;
+        if (co_noteon_on[0] < -0.5)
+            return; // don't redamp notes in shutdown stage
+
+        sustain = true;
+        co_noteon_on[0] = 1;
+
+        int[] c = performer.midi_connections[3];
+        if (c == null)
+            return;
+        for (int i = 0; i < c.length; i++)
+            processConnection(c[i]);
+    }
+
+    protected void processControlLogic() {
+        if (stopping) {
+            active = false;
+            stopping = false;
+            audiostarted = false;
+            if (osc_stream != null)
+                try {
+                    osc_stream.close();
+                } catch (IOException e) {
+                    //e.printStackTrace();
+                }
+
+            if (stealer_channel != null) {
+                stealer_channel.initVoice(this, stealer_performer,
+                        stealer_voiceID, stealer_noteNumber, stealer_velocity,
+                        stealer_extendedConnectionBlocks, stealer_channelmixer,
+                        stealer_releaseTriggered);
+                stealer_releaseTriggered = false;
+                stealer_channel = null;
+                stealer_performer = null;
+                stealer_voiceID = -1;
+                stealer_noteNumber = 0;
+                stealer_velocity = 0;
+                stealer_extendedConnectionBlocks = null;
+                stealer_channelmixer = null;
+            }
+        }
+        if (started) {
+            audiostarted = true;
+
+            ModelOscillator osc = performer.oscillators[0];
+
+            osc_stream_off_transmitted = false;
+            if (osc instanceof ModelWavetable) {
+                try {
+                    resampler.open((ModelWavetable)osc,
+                            synthesizer.getFormat().getSampleRate());
+                    osc_stream = resampler;
+                } catch (IOException e) {
+                    //e.printStackTrace();
+                }
+            } else {
+                osc_stream = osc.open(synthesizer.getFormat().getSampleRate());
+            }
+            osc_attenuation = osc.getAttenuation();
+            osc_stream_nrofchannels = osc.getChannels();
+            if (osc_buff == null || osc_buff.length < osc_stream_nrofchannels)
+                osc_buff = new float[osc_stream_nrofchannels][];
+
+            if (osc_stream != null)
+                osc_stream.noteOn(softchannel, this, noteOn_noteNumber,
+                        noteOn_velocity);
+
+
+        }
+        if (audiostarted) {
+            if (portamento) {
+                double note_delta = tunedKey - (co_noteon_keynumber[0] * 128);
+                double note_delta_a = Math.abs(note_delta);
+                if (note_delta_a < 0.0000000001) {
+                    co_noteon_keynumber[0] = tunedKey * (1.0 / 128.0);
+                    portamento = false;
+                } else {
+                    if (note_delta_a > softchannel.portamento_time)
+                        note_delta = Math.signum(note_delta)
+                                * softchannel.portamento_time;
+                    co_noteon_keynumber[0] += note_delta * (1.0 / 128.0);
+                }
+
+                int[] c = performer.midi_connections[4];
+                if (c == null)
+                    return;
+                for (int i = 0; i < c.length; i++)
+                    processConnection(c[i]);
+            }
+
+            eg.processControlLogic();
+            lfo.processControlLogic();
+
+            for (int i = 0; i < performer.ctrl_connections.length; i++)
+                processConnection(performer.ctrl_connections[i]);
+
+            osc_stream.setPitch((float)co_osc_pitch[0]);
+
+            int filter_type = (int)co_filter_type[0];
+            double filter_freq;
+
+            if (co_filter_freq[0] == 13500.0)
+                filter_freq = 19912.126958213175;
+            else
+                filter_freq = 440.0 * Math.exp(
+                        ((co_filter_freq[0]) - 6900.0) *
+                        (Math.log(2.0) / 1200.0));
+            /*
+            filter_freq = 440.0 * Math.pow(2.0,
+            ((co_filter_freq[0]) - 6900.0) / 1200.0);*/
+            /*
+             * double velocity = co_noteon_velocity[0]; if(velocity < 0.5)
+             * filter_freq *= ((velocity * 2)*0.75 + 0.25);
+             */
+
+            double q = co_filter_q[0] / 10.0;
+            filter_left.setFilterType(filter_type);
+            filter_left.setFrequency(filter_freq);
+            filter_left.setResonance(q);
+            filter_right.setFilterType(filter_type);
+            filter_right.setFrequency(filter_freq);
+            filter_right.setResonance(q);
+            /*
+            float gain = (float) Math.pow(10,
+            (-osc_attenuation + co_mixer_gain[0]) / 200.0);
+             */
+            float gain = (float)Math.exp(
+                    (-osc_attenuation + co_mixer_gain[0])*(Math.log(10) / 200.0));
+
+            if (co_mixer_gain[0] <= -960)
+                gain = 0;
+
+            if (soundoff) {
+                stopping = true;
+                gain = 0;
+                /*
+                 * if(co_mixer_gain[0] > -960)
+                 *   co_mixer_gain[0] -= 960;
+                 */
+            }
+
+            volume = (int)(Math.sqrt(gain) * 128);
+
+            // gain *= 0.2;
+
+            double pan = co_mixer_pan[0] * (1.0 / 1000.0);
+            // System.out.println("pan = " + pan);
+            if (pan < 0)
+                pan = 0;
+            else if (pan > 1)
+                pan = 1;
+
+            if (pan == 0.5) {
+                out_mixer_left = gain * 0.7071067811865476f;
+                out_mixer_right = out_mixer_left;
+            } else {
+                out_mixer_left = gain * (float)Math.cos(pan * Math.PI * 0.5);
+                out_mixer_right = gain * (float)Math.sin(pan * Math.PI * 0.5);
+            }
+
+            double balance = co_mixer_balance[0] * (1.0 / 1000.0);
+            if (balance != 0.5) {
+                if (balance > 0.5)
+                    out_mixer_left *= (1 - balance) * 2;
+                else
+                    out_mixer_right *= balance * 2;
+            }
+
+            if (synthesizer.reverb_on) {
+                out_mixer_effect1 = (float)(co_mixer_reverb[0] * (1.0 / 1000.0));
+                out_mixer_effect1 *= gain;
+            } else
+                out_mixer_effect1 = 0;
+            if (synthesizer.chorus_on) {
+                out_mixer_effect2 = (float)(co_mixer_chorus[0] * (1.0 / 1000.0));
+                out_mixer_effect2 *= gain;
+            } else
+                out_mixer_effect2 = 0;
+            out_mixer_end = co_mixer_active[0] < 0.5;
+
+            if (!on)
+                if (!osc_stream_off_transmitted) {
+                    osc_stream_off_transmitted = true;
+                    if (osc_stream != null)
+                        osc_stream.noteOff(noteOff_velocity);
+                }
+
+        }
+        if (started) {
+            last_out_mixer_left = out_mixer_left;
+            last_out_mixer_right = out_mixer_right;
+            last_out_mixer_effect1 = out_mixer_effect1;
+            last_out_mixer_effect2 = out_mixer_effect2;
+            started = false;
+        }
+
+    }
+
+    protected void mixAudioStream(SoftAudioBuffer in, SoftAudioBuffer out,
+            float amp_from, float amp_to) {
+        int bufferlen = in.getSize();
+        if (amp_from < 0.000000001 && amp_to < 0.000000001)
+            return;
+        if (amp_from == amp_to) {
+            float[] fout = out.array();
+            float[] fin = in.array();
+            for (int i = 0; i < bufferlen; i++)
+                fout[i] += fin[i] * amp_to;
+        } else {
+            float amp = amp_from;
+            float amp_delta = (amp_to - amp_from) / bufferlen;
+            float[] fout = out.array();
+            float[] fin = in.array();
+            for (int i = 0; i < bufferlen; i++) {
+                amp += amp_delta;
+                fout[i] += fin[i] * amp;
+            }
+        }
+
+    }
+
+    protected void processAudioLogic(SoftAudioBuffer[] buffer) {
+        if (!audiostarted)
+            return;
+
+        int bufferlen = buffer[0].getSize();
+
+        try {
+            osc_buff[0] = buffer[SoftMainMixer.CHANNEL_LEFT_DRY].array();
+            if (nrofchannels != 1)
+                osc_buff[1] = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY].array();
+            int ret = osc_stream.read(osc_buff, 0, bufferlen);
+            if (ret == -1) {
+                stopping = true;
+                return;
+            }
+            if (ret != bufferlen) {
+                Arrays.fill(osc_buff[0], ret, bufferlen, 0f);
+                if (nrofchannels != 1)
+                    Arrays.fill(osc_buff[1], ret, bufferlen, 0f);
+            }
+
+        } catch (IOException e) {
+            //e.printStackTrace();
+        }
+
+        SoftAudioBuffer left = buffer[SoftMainMixer.CHANNEL_LEFT];
+        SoftAudioBuffer right = buffer[SoftMainMixer.CHANNEL_RIGHT];
+        SoftAudioBuffer eff1 = buffer[SoftMainMixer.CHANNEL_EFFECT1];
+        SoftAudioBuffer eff2 = buffer[SoftMainMixer.CHANNEL_EFFECT2];
+        SoftAudioBuffer leftdry = buffer[SoftMainMixer.CHANNEL_LEFT_DRY];
+        SoftAudioBuffer rightdry = buffer[SoftMainMixer.CHANNEL_RIGHT_DRY];
+
+        if (osc_stream_nrofchannels == 1)
+            rightdry = null;
+
+        if (!Double.isInfinite(co_filter_freq[0])) {
+            filter_left.processAudio(leftdry);
+            if (rightdry != null)
+                filter_right.processAudio(rightdry);
+        }
+
+        if (nrofchannels == 1) {
+            out_mixer_left = (out_mixer_left + out_mixer_right) / 2;
+            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
+            if (rightdry != null)
+                mixAudioStream(rightdry, left, last_out_mixer_left,
+                        out_mixer_left);
+        } else {
+            mixAudioStream(leftdry, left, last_out_mixer_left, out_mixer_left);
+            if (rightdry != null)
+                mixAudioStream(rightdry, right, last_out_mixer_right,
+                        out_mixer_right);
+            else
+                mixAudioStream(leftdry, right, last_out_mixer_right,
+                        out_mixer_right);
+        }
+
+        if (rightdry == null) {
+            mixAudioStream(leftdry, eff1, last_out_mixer_effect1,
+                    out_mixer_effect1);
+            mixAudioStream(leftdry, eff2, last_out_mixer_effect2,
+                    out_mixer_effect2);
+        } else {
+            mixAudioStream(leftdry, eff1, last_out_mixer_effect1 * 0.5f,
+                    out_mixer_effect1 * 0.5f);
+            mixAudioStream(leftdry, eff2, last_out_mixer_effect2 * 0.5f,
+                    out_mixer_effect2 * 0.5f);
+            mixAudioStream(rightdry, eff1, last_out_mixer_effect1 * 0.5f,
+                    out_mixer_effect1 * 0.5f);
+            mixAudioStream(rightdry, eff2, last_out_mixer_effect2 * 0.5f,
+                    out_mixer_effect2 * 0.5f);
+        }
+
+        last_out_mixer_left = out_mixer_left;
+        last_out_mixer_right = out_mixer_right;
+        last_out_mixer_effect1 = out_mixer_effect1;
+        last_out_mixer_effect2 = out_mixer_effect2;
+
+        if (out_mixer_end) {
+            stopping = true;
+        }
+
+    }
+}
--- a/jdk/src/share/classes/com/sun/media/sound/WaveFloatFileReader.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/com/sun/media/sound/WaveFloatFileReader.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,167 +1,167 @@
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-package com.sun.media.sound;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-
-import javax.sound.sampled.AudioFileFormat;
-import javax.sound.sampled.AudioFormat;
-import javax.sound.sampled.AudioInputStream;
-import javax.sound.sampled.AudioSystem;
-import javax.sound.sampled.UnsupportedAudioFileException;
-import javax.sound.sampled.spi.AudioFileReader;
-
-/**
- * Floating-point encoded (format 3) WAVE file loader.
- *
- * @author Karl Helgason
- */
-public class WaveFloatFileReader extends AudioFileReader {
-
-    public AudioFileFormat getAudioFileFormat(InputStream stream)
-            throws UnsupportedAudioFileException, IOException {
-
-        stream.mark(200);
-        AudioFileFormat format;
-        try {
-            format = internal_getAudioFileFormat(stream);
-        } finally {
-            stream.reset();
-        }
-        return format;
-    }
-
-    private AudioFileFormat internal_getAudioFileFormat(InputStream stream)
-            throws UnsupportedAudioFileException, IOException {
-
-        RIFFReader riffiterator = new RIFFReader(stream);
-        if (!riffiterator.getFormat().equals("RIFF"))
-            throw new UnsupportedAudioFileException();
-        if (!riffiterator.getType().equals("WAVE"))
-            throw new UnsupportedAudioFileException();
-
-        boolean fmt_found = false;
-        boolean data_found = false;
-
-        int channels = 1;
-        long samplerate = 1;
-        long framerate = 1;
-        int framesize = 1;
-        int bits = 1;
-
-        while (riffiterator.hasNextChunk()) {
-            RIFFReader chunk = riffiterator.nextChunk();
-
-            if (chunk.getFormat().equals("fmt ")) {
-                fmt_found = true;
-
-                int format = chunk.readUnsignedShort();
-                if (format != 3) // WAVE_FORMAT_IEEE_FLOAT only
-                    throw new UnsupportedAudioFileException();
-                channels = chunk.readUnsignedShort();
-                samplerate = chunk.readUnsignedInt();
-                framerate = chunk.readUnsignedInt();
-                framesize = chunk.readUnsignedShort();
-                bits = chunk.readUnsignedShort();
-            }
-            if (chunk.getFormat().equals("data")) {
-                data_found = true;
-                break;
-            }
-        }
-
-        if (!fmt_found)
-            throw new UnsupportedAudioFileException();
-        if (!data_found)
-            throw new UnsupportedAudioFileException();
-
-        AudioFormat audioformat = new AudioFormat(
-                AudioFloatConverter.PCM_FLOAT, samplerate, bits, channels,
-                framesize, framerate, false);
-        AudioFileFormat fileformat = new AudioFileFormat(
-                AudioFileFormat.Type.WAVE, audioformat,
-                AudioSystem.NOT_SPECIFIED);
-        return fileformat;
-    }
-
-    public AudioInputStream getAudioInputStream(InputStream stream)
-            throws UnsupportedAudioFileException, IOException {
-
-        AudioFileFormat format = getAudioFileFormat(stream);
-        RIFFReader riffiterator = new RIFFReader(stream);
-        if (!riffiterator.getFormat().equals("RIFF"))
-            throw new UnsupportedAudioFileException();
-        if (!riffiterator.getType().equals("WAVE"))
-            throw new UnsupportedAudioFileException();
-        while (riffiterator.hasNextChunk()) {
-            RIFFReader chunk = riffiterator.nextChunk();
-            if (chunk.getFormat().equals("data")) {
-                return new AudioInputStream(chunk, format.getFormat(),
-                        chunk.getSize());
-            }
-        }
-        throw new UnsupportedAudioFileException();
-    }
-
-    public AudioFileFormat getAudioFileFormat(URL url)
-            throws UnsupportedAudioFileException, IOException {
-        InputStream stream = url.openStream();
-        AudioFileFormat format;
-        try {
-            format = getAudioFileFormat(new BufferedInputStream(stream));
-        } finally {
-            stream.close();
-        }
-        return format;
-    }
-
-    public AudioFileFormat getAudioFileFormat(File file)
-            throws UnsupportedAudioFileException, IOException {
-        InputStream stream = new FileInputStream(file);
-        AudioFileFormat format;
-        try {
-            format = getAudioFileFormat(new BufferedInputStream(stream));
-        } finally {
-            stream.close();
-        }
-        return format;
-    }
-
-    public AudioInputStream getAudioInputStream(URL url)
-            throws UnsupportedAudioFileException, IOException {
-        return getAudioInputStream(new BufferedInputStream(url.openStream()));
-    }
-
-    public AudioInputStream getAudioInputStream(File file)
-            throws UnsupportedAudioFileException, IOException {
-        return getAudioInputStream(new BufferedInputStream(new FileInputStream(
-                file)));
-    }
-}
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.media.sound;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import javax.sound.sampled.AudioFileFormat;
+import javax.sound.sampled.AudioFormat;
+import javax.sound.sampled.AudioInputStream;
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.UnsupportedAudioFileException;
+import javax.sound.sampled.spi.AudioFileReader;
+
+/**
+ * Floating-point encoded (format 3) WAVE file loader.
+ *
+ * @author Karl Helgason
+ */
+public class WaveFloatFileReader extends AudioFileReader {
+
+    public AudioFileFormat getAudioFileFormat(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        stream.mark(200);
+        AudioFileFormat format;
+        try {
+            format = internal_getAudioFileFormat(stream);
+        } finally {
+            stream.reset();
+        }
+        return format;
+    }
+
+    private AudioFileFormat internal_getAudioFileFormat(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        RIFFReader riffiterator = new RIFFReader(stream);
+        if (!riffiterator.getFormat().equals("RIFF"))
+            throw new UnsupportedAudioFileException();
+        if (!riffiterator.getType().equals("WAVE"))
+            throw new UnsupportedAudioFileException();
+
+        boolean fmt_found = false;
+        boolean data_found = false;
+
+        int channels = 1;
+        long samplerate = 1;
+        long framerate = 1;
+        int framesize = 1;
+        int bits = 1;
+
+        while (riffiterator.hasNextChunk()) {
+            RIFFReader chunk = riffiterator.nextChunk();
+
+            if (chunk.getFormat().equals("fmt ")) {
+                fmt_found = true;
+
+                int format = chunk.readUnsignedShort();
+                if (format != 3) // WAVE_FORMAT_IEEE_FLOAT only
+                    throw new UnsupportedAudioFileException();
+                channels = chunk.readUnsignedShort();
+                samplerate = chunk.readUnsignedInt();
+                framerate = chunk.readUnsignedInt();
+                framesize = chunk.readUnsignedShort();
+                bits = chunk.readUnsignedShort();
+            }
+            if (chunk.getFormat().equals("data")) {
+                data_found = true;
+                break;
+            }
+        }
+
+        if (!fmt_found)
+            throw new UnsupportedAudioFileException();
+        if (!data_found)
+            throw new UnsupportedAudioFileException();
+
+        AudioFormat audioformat = new AudioFormat(
+                AudioFloatConverter.PCM_FLOAT, samplerate, bits, channels,
+                framesize, framerate, false);
+        AudioFileFormat fileformat = new AudioFileFormat(
+                AudioFileFormat.Type.WAVE, audioformat,
+                AudioSystem.NOT_SPECIFIED);
+        return fileformat;
+    }
+
+    public AudioInputStream getAudioInputStream(InputStream stream)
+            throws UnsupportedAudioFileException, IOException {
+
+        AudioFileFormat format = getAudioFileFormat(stream);
+        RIFFReader riffiterator = new RIFFReader(stream);
+        if (!riffiterator.getFormat().equals("RIFF"))
+            throw new UnsupportedAudioFileException();
+        if (!riffiterator.getType().equals("WAVE"))
+            throw new UnsupportedAudioFileException();
+        while (riffiterator.hasNextChunk()) {
+            RIFFReader chunk = riffiterator.nextChunk();
+            if (chunk.getFormat().equals("data")) {
+                return new AudioInputStream(chunk, format.getFormat(),
+                        chunk.getSize());
+            }
+        }
+        throw new UnsupportedAudioFileException();
+    }
+
+    public AudioFileFormat getAudioFileFormat(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        InputStream stream = url.openStream();
+        AudioFileFormat format;
+        try {
+            format = getAudioFileFormat(new BufferedInputStream(stream));
+        } finally {
+            stream.close();
+        }
+        return format;
+    }
+
+    public AudioFileFormat getAudioFileFormat(File file)
+            throws UnsupportedAudioFileException, IOException {
+        InputStream stream = new FileInputStream(file);
+        AudioFileFormat format;
+        try {
+            format = getAudioFileFormat(new BufferedInputStream(stream));
+        } finally {
+            stream.close();
+        }
+        return format;
+    }
+
+    public AudioInputStream getAudioInputStream(URL url)
+            throws UnsupportedAudioFileException, IOException {
+        return getAudioInputStream(new BufferedInputStream(url.openStream()));
+    }
+
+    public AudioInputStream getAudioInputStream(File file)
+            throws UnsupportedAudioFileException, IOException {
+        return getAudioInputStream(new BufferedInputStream(new FileInputStream(
+                file)));
+    }
+}
--- a/jdk/src/share/classes/java/awt/Component.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/java/awt/Component.java	Thu Jul 10 00:00:00 2008 +0200
@@ -634,6 +634,11 @@
      */
     private PropertyChangeSupport changeSupport;
 
+    private transient final Object changeSupportLock = new Object();
+    private Object getChangeSupportLock() {
+        return changeSupportLock;
+    }
+
     boolean isPacked = false;
 
     /**
@@ -7838,15 +7843,17 @@
      * @see #getPropertyChangeListeners
      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
      */
-    public synchronized void addPropertyChangeListener(
+    public void addPropertyChangeListener(
                                                        PropertyChangeListener listener) {
-        if (listener == null) {
-            return;
-        }
-        if (changeSupport == null) {
-            changeSupport = new PropertyChangeSupport(this);
-        }
-        changeSupport.addPropertyChangeListener(listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null) {
+                return;
+            }
+            if (changeSupport == null) {
+                changeSupport = new PropertyChangeSupport(this);
+            }
+            changeSupport.addPropertyChangeListener(listener);
+        }
     }
 
     /**
@@ -7862,12 +7869,14 @@
      * @see #getPropertyChangeListeners
      * @see #removePropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
      */
-    public synchronized void removePropertyChangeListener(
+    public void removePropertyChangeListener(
                                                           PropertyChangeListener listener) {
-        if (listener == null || changeSupport == null) {
-            return;
-        }
-        changeSupport.removePropertyChangeListener(listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null || changeSupport == null) {
+                return;
+            }
+            changeSupport.removePropertyChangeListener(listener);
+        }
     }
 
     /**
@@ -7884,11 +7893,13 @@
      * @see      java.beans.PropertyChangeSupport#getPropertyChangeListeners
      * @since    1.4
      */
-    public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
-        if (changeSupport == null) {
-            return new PropertyChangeListener[0];
-        }
-        return changeSupport.getPropertyChangeListeners();
+    public PropertyChangeListener[] getPropertyChangeListeners() {
+        synchronized (getChangeSupportLock()) {
+            if (changeSupport == null) {
+                return new PropertyChangeListener[0];
+            }
+            return changeSupport.getPropertyChangeListeners();
+        }
     }
 
     /**
@@ -7922,16 +7933,18 @@
      * @see #getPropertyChangeListeners(java.lang.String)
      * @see #addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
      */
-    public synchronized void addPropertyChangeListener(
+    public void addPropertyChangeListener(
                                                        String propertyName,
                                                        PropertyChangeListener listener) {
-        if (listener == null) {
-            return;
-        }
-        if (changeSupport == null) {
-            changeSupport = new PropertyChangeSupport(this);
-        }
-        changeSupport.addPropertyChangeListener(propertyName, listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null) {
+                return;
+            }
+            if (changeSupport == null) {
+                changeSupport = new PropertyChangeSupport(this);
+            }
+            changeSupport.addPropertyChangeListener(propertyName, listener);
+        }
     }
 
     /**
@@ -7950,13 +7963,15 @@
      * @see #getPropertyChangeListeners(java.lang.String)
      * @see #removePropertyChangeListener(java.beans.PropertyChangeListener)
      */
-    public synchronized void removePropertyChangeListener(
+    public void removePropertyChangeListener(
                                                           String propertyName,
                                                           PropertyChangeListener listener) {
-        if (listener == null || changeSupport == null) {
-            return;
-        }
-        changeSupport.removePropertyChangeListener(propertyName, listener);
+        synchronized (getChangeSupportLock()) {
+            if (listener == null || changeSupport == null) {
+                return;
+            }
+            changeSupport.removePropertyChangeListener(propertyName, listener);
+        }
     }
 
     /**
@@ -7973,12 +7988,14 @@
      * @see #getPropertyChangeListeners
      * @since 1.4
      */
-    public synchronized PropertyChangeListener[] getPropertyChangeListeners(
+    public PropertyChangeListener[] getPropertyChangeListeners(
                                                                             String propertyName) {
-        if (changeSupport == null) {
-            return new PropertyChangeListener[0];
-        }
-        return changeSupport.getPropertyChangeListeners(propertyName);
+        synchronized (getChangeSupportLock()) {
+            if (changeSupport == null) {
+                return new PropertyChangeListener[0];
+            }
+            return changeSupport.getPropertyChangeListeners(propertyName);
+        }
     }
 
     /**
@@ -7993,7 +8010,10 @@
      */
     protected void firePropertyChange(String propertyName,
                                       Object oldValue, Object newValue) {
-        PropertyChangeSupport changeSupport = this.changeSupport;
+        PropertyChangeSupport changeSupport;
+        synchronized (getChangeSupportLock()) {
+            changeSupport = this.changeSupport;
+        }
         if (changeSupport == null ||
             (oldValue != null && newValue != null && oldValue.equals(newValue))) {
             return;
--- a/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/java/awt/dnd/DragSourceContext.java	Thu Jul 10 00:00:00 2008 +0200
@@ -466,8 +466,9 @@
 
         Cursor c = null;
 
-        targetAct = DnDConstants.ACTION_NONE;
         switch (status) {
+            default:
+                targetAct = DnDConstants.ACTION_NONE;
             case ENTER:
             case OVER:
             case CHANGED:
--- a/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java	Thu Jul 10 00:00:00 2008 +0200
@@ -94,6 +94,7 @@
     public static interface DefaultValues {
         public static final String PORT="0";
         public static final String CONFIG_FILE_NAME="management.properties";
+        public static final String USE_LOCAL_ONLY="true";
         public static final String USE_SSL="true";
         public static final String USE_REGISTRY_SSL="false";
         public static final String USE_AUTHENTICATION="true";
@@ -110,6 +111,8 @@
                 "com.sun.management.jmxremote.port";
         public static final String CONFIG_FILE_NAME =
                 "com.sun.management.config.file";
+        public static final String USE_LOCAL_ONLY =
+                "com.sun.management.jmxremote.local.only";
         public static final String USE_SSL =
                 "com.sun.management.jmxremote.ssl";
         public static final String USE_REGISTRY_SSL =
@@ -255,7 +258,6 @@
 
         final String portStr = props.getProperty(PropertyNames.PORT);
 
-
         // System.out.println("initializing: {port=" + portStr + ",
         //                     properties="+props+"}");
         return initialize(portStr,props);
@@ -442,6 +444,18 @@
         MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
         try {
             JMXServiceURL url = new JMXServiceURL("rmi", localhost, 0);
+            // Do we accept connections from local interfaces only?
+            Properties props = Agent.getManagementProperties();
+            if (props ==  null) {
+                props = new Properties();
+            }
+            String useLocalOnlyStr = props.getProperty(
+                    PropertyNames.USE_LOCAL_ONLY, DefaultValues.USE_LOCAL_ONLY);
+            boolean useLocalOnly = Boolean.valueOf(useLocalOnlyStr).booleanValue();
+            if (useLocalOnly) {
+                env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
+                        new LocalRMIServerSocketFactory());
+            }
             JMXConnectorServer server =
                     JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
             server.start();
@@ -489,12 +503,11 @@
         if (!file.exists()) {
             throw new AgentConfigurationError(ACCESS_FILE_NOT_FOUND, accessFileName);
         }
-
         if (!file.canRead()) {
             throw new AgentConfigurationError(ACCESS_FILE_NOT_READABLE, accessFileName);
         }
     }
-
+    
     private static void checkRestrictedFile(String restrictedFileName) {
         if (restrictedFileName == null || restrictedFileName.length() == 0) {
             throw new AgentConfigurationError(FILE_NOT_SET);
@@ -726,5 +739,4 @@
     private static final ClassLogger log =
         new ClassLogger(ConnectorBootstrap.class.getPackage().getName(),
                         "ConnectorBootstrap");
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.management.jmxremote;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Enumeration;
+
+/**
+ * This RMI server socket factory creates server sockets that
+ * will only accept connection requests from clients running
+ * on the host where the RMI remote objects have been exported.
+ */
+public final class LocalRMIServerSocketFactory implements RMIServerSocketFactory {
+    /**
+     * Creates a server socket that only accepts connection requests from
+     * clients running on the host where the RMI remote objects have been
+     * exported.
+     */
+    public ServerSocket createServerSocket(int port) throws IOException {
+        return new ServerSocket(port) {
+            @Override
+            public Socket accept() throws IOException {
+                Socket socket = super.accept();
+                InetAddress remoteAddr = socket.getInetAddress();
+                final String msg = "The server sockets created using the " +
+                        "LocalRMIServerSocketFactory only accept connections " +
+                        "from clients running on the host where the RMI " +
+                        "remote objects have been exported.";
+                // Retrieve all the network interfaces on this host.
+                Enumeration<NetworkInterface> nis;
+                try {
+                    nis = NetworkInterface.getNetworkInterfaces();
+                } catch (SocketException e) {
+                    try {
+                        socket.close();
+                    } catch (IOException ioe) {
+                        // Ignore...
+                    }
+                    throw new IOException(msg, e);
+                }
+                // Walk through the network interfaces to see
+                // if any of them matches the client's address.
+                // If true, then the client's address is local.
+                while (nis.hasMoreElements()) {
+                    NetworkInterface ni = nis.nextElement();
+                    Enumeration<InetAddress> addrs = ni.getInetAddresses();
+                    while (addrs.hasMoreElements()) {
+                        InetAddress localAddr = addrs.nextElement();
+                        if (localAddr.equals(remoteAddr)) {
+                            return socket;
+                        }
+                    }
+                }
+                // The client's address is remote so refuse the connection.
+                try {
+                    socket.close();
+                } catch (IOException ioe) {
+                    // Ignore...
+                }
+                throw new IOException(msg);
+            }
+        };
+    }
+
+    /**
+     * Two LocalRMIServerSocketFactory objects
+     * are equal if they are of the same type.
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return (obj instanceof LocalRMIServerSocketFactory);
+    }
+
+    /**
+     * Returns a hash code value for this LocalRMIServerSocketFactory.
+     */
+    @Override
+    public int hashCode() {
+        return getClass().hashCode();
+    }
+}
--- a/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/classes/sun/nio/ch/NativeThreadSet.java	Thu Jul 10 00:00:00 2008 +0200
@@ -43,7 +43,7 @@
     //
     int add() {
         long th = NativeThread.current();
-        if (th <= 0)
+        if (th == -1)
             return -1;
         synchronized (this) {
             int start = 0;
--- a/jdk/src/share/lib/management/management.properties	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/lib/management/management.properties	Thu Jul 10 00:00:00 2008 +0200
@@ -82,7 +82,7 @@
 #
 # com.sun.management.snmp.interface=<InetAddress>
 #      Specifies the local interface on which the SNMP agent will bind.
-#      This is usefull when running on machines which have several
+#      This is useful when running on machines which have several
 #      interfaces defined. It makes it possible to listen to a specific
 #      subnet accessible through that interface.
 #      Default for this property is "localhost".
@@ -144,6 +144,26 @@
 #
 
 #
+# ########## RMI connector settings for local management ##########
+#
+# com.sun.management.jmxremote.local.only=true|false
+#      Default for this property is true. (Case for true/false ignored)
+#      If this property is specified as true then the local JMX RMI connector
+#      server will only accept connection requests from clients running on
+#      the host where the out-of-the-box JMX management agent is running.
+#      In order to ensure backwards compatibility this property could be
+#      set to false. However, deploying the local management agent in this
+#      way is discouraged because the local JMX RMI connector server will
+#      accept connection requests from any client either local or remote.
+#      For remote management the remote JMX RMI connector server should
+#      be used instead with authentication and SSL/TLS encryption enabled.
+#
+
+# For allowing the local management agent accept local
+# and remote connection requests use the following line
+# com.sun.management.jmxremote.local.only=false
+
+#
 # ###################### RMI SSL #############################
 #
 # com.sun.management.jmxremote.ssl=true|false
--- a/jdk/src/share/native/sun/font/bidi/ubidi.c	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/share/native/sun/font/bidi/ubidi.c	Thu Jul 10 00:00:00 2008 +0200
@@ -384,23 +384,23 @@
         return;
     }
 
-    /* are explicit levels specified? */
-    if(embeddingLevels==NULL) {
-        /* no: determine explicit levels according to the (Xn) rules */\
-        if(getLevelsMemory(pBiDi, length)) {
-            pBiDi->levels=pBiDi->levelsMemory;
+    if (getLevelsMemory(pBiDi, length)) {
+        pBiDi->levels=pBiDi->levelsMemory;
+        /* are explicit levels specified? */
+        if(embeddingLevels==NULL) {
+            /* no: determine explicit levels according to the (Xn) rules */
             direction=resolveExplicitLevels(pBiDi);
         } else {
-            *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
-            return;
+            /* set BN for all explicit codes, check that all levels are paraLevel..UBIDI_MAX_EXPLICIT_LEVEL */
+            icu_memcpy(pBiDi->levels, embeddingLevels, length);
+            direction=checkExplicitLevels(pBiDi, pErrorCode);
+            if(U_FAILURE(*pErrorCode)) {
+                 return;
+            }
         }
     } else {
-        /* set BN for all explicit codes, check that all levels are paraLevel..UBIDI_MAX_EXPLICIT_LEVEL */
-        pBiDi->levels=embeddingLevels;
-        direction=checkExplicitLevels(pBiDi, pErrorCode);
-        if(U_FAILURE(*pErrorCode)) {
-            return;
-        }
+        *pErrorCode=U_MEMORY_ALLOCATION_ERROR;
+        return;
     }
 
     /*
--- a/jdk/src/solaris/classes/sun/nio/ch/NativeThread.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/solaris/classes/sun/nio/ch/NativeThread.java	Thu Jul 10 00:00:00 2008 +0200
@@ -34,14 +34,14 @@
 // upon which Java threads are built, and defines a simple signal mechanism
 // that can be used to release a native thread from a blocking I/O operation.
 // On systems that do not require this type of signalling, the current() method
-// always returns zero and the signal(long) method has no effect.
+// always returns -1 and the signal(long) method has no effect.
 
 
 class NativeThread {
 
     // Returns an opaque token representing the native thread underlying the
     // invoking Java thread.  On systems that do not require signalling, this
-    // method always returns zero.
+    // method always returns -1.
     //
     static native long current();
 
--- a/jdk/src/solaris/native/sun/awt/gtk2_interface.c	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/solaris/native/sun/awt/gtk2_interface.c	Thu Jul 10 00:00:00 2008 +0200
@@ -333,6 +333,7 @@
 static GdkPixbuf* (*fp_gtk_widget_render_icon)(GtkWidget *widget,
         const gchar *stock_id, GtkIconSize size, const gchar *detail);
 static void (*fp_gtk_widget_set_name)(GtkWidget *widget, const gchar *name);
+static void (*fp_gtk_widget_set_parent)(GtkWidget *widget, GtkWidget *parent);
 static void (*fp_gtk_widget_set_direction)(GtkWidget *widget,
         GtkTextDirection direction);
 static void (*fp_gtk_widget_style_get)(GtkWidget *widget,
@@ -570,6 +571,8 @@
             dl_symbol("gtk_widget_render_icon");
         fp_gtk_widget_set_name =
             dl_symbol("gtk_widget_set_name");
+        fp_gtk_widget_set_parent =
+            dl_symbol("gtk_widget_set_parent");
         fp_gtk_widget_set_direction =
             dl_symbol("gtk_widget_set_direction");
         fp_gtk_widget_style_get =
@@ -1040,7 +1043,7 @@
                     (NULL == gtk2_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE]))
             {
                 gtk2_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE] =
-                     (*fp_gtk_button_new)();
+                     (*fp_gtk_toggle_button_new)();
             }
             result = gtk2_widgets[_GTK_COMBO_BOX_ARROW_BUTTON_TYPE];
             break;
@@ -1414,12 +1417,20 @@
                  widget_type == COMBO_BOX_TEXT_FIELD)
         {
             /*
-             * We add a regular GtkButton/GtkEntry to a GtkComboBoxEntry
-             * in order to trick engines into thinking it's a real combobox
-             * arrow button/text field.
-             */
+            * We add a regular GtkButton/GtkEntry to a GtkComboBoxEntry
+            * in order to trick engines into thinking it's a real combobox
+            * arrow button/text field.
+            */
             GtkWidget *combo = (*fp_gtk_combo_box_entry_new)();
-            (*fp_gtk_container_add)((GtkContainer *)combo, result);
+
+            if (widget_type == COMBO_BOX_TEXT_FIELD)
+                (*fp_gtk_container_add)((GtkContainer *)combo, result);
+            else
+            {
+                (*fp_gtk_widget_set_parent)(result, combo);
+                ((GtkBin*)combo)->child = result;
+            }
+
             (*fp_gtk_container_add)((GtkContainer *)gtk2_fixed, combo);
             (*fp_gtk_widget_realize)(result);
             return result;
--- a/jdk/src/windows/classes/sun/nio/ch/NativeThread.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/src/windows/classes/sun/nio/ch/NativeThread.java	Thu Jul 10 00:00:00 2008 +0200
@@ -31,7 +31,7 @@
 
 class NativeThread {
 
-    static long current() { return 0; }
+    static long current() { return -1; }
 
     static void signal(long nt) { }
 
--- a/jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/test/java/nio/channels/AsyncCloseAndInterrupt.java	Thu Jul 10 00:00:00 2008 +0200
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4460583 4470470 4840199 6419424
+ * @bug 4460583 4470470 4840199 6419424 6710579 6596323
  * @summary Comprehensive test of asynchronous closing and interruption
  * @author Mark Reinhold
  */
@@ -582,7 +582,7 @@
             log.println("WARNING: transferFrom/close not tested");
             return;
         }
-        if ((op == TRANSFER_TO) && TestUtil.onSolaris()) {
+        if ((op == TRANSFER_TO) && !TestUtil.onWindows()) {
             log.println("WARNING: transferTo/close not tested");
             return;
         }
--- a/jdk/test/java/nio/channels/DatagramChannel/NotBound.java	Fri May 30 00:00:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright 2002 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-/* @test
- * @bug 4512723
- * @summary Unit test for datagram-socket-channel adaptors
- */
-
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
-
-class NotBound {
-    public static void main(String[] args) throws Exception {
-        test1(false);
-        test1(true);
-    }
-
-    static void test1(boolean blocking) throws Exception {
-        ByteBuffer bb = ByteBuffer.allocateDirect(256);
-        DatagramChannel dc1 = DatagramChannel.open();
-        dc1.configureBlocking(false);
-        SocketAddress isa = dc1.receive(bb);
-        if (isa != null)
-            throw new Exception("Unbound dc returned non-null");
-        dc1.close();
-    }
-}
--- a/jdk/test/java/nio/channels/SocketChannel/AsyncCloseChannel.java	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/test/java/nio/channels/SocketChannel/AsyncCloseChannel.java	Thu Jul 10 00:00:00 2008 +0200
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 6285901
+ * @bug 6285901 6501089
  * @summary Check no data is written to wrong socket channel during async closing.
  * @author Xueming Shen
  */
@@ -33,13 +33,13 @@
 import java.net.*;
 
 public class AsyncCloseChannel {
-    static boolean failed = false;
-    static boolean keepGoing = true;
+    static volatile boolean failed = false;
+    static volatile boolean keepGoing = true;
+    static int maxAcceptCount = 100;
+    static volatile int acceptCount = 0;
     static String host = "127.0.0.1";
-    static int sensorPort = 3010;
-    static int targetPort = 3020;
-    static int maxAcceptCount = 1000;
-    static int acceptCount = 0;
+    static int sensorPort;
+    static int targetPort;
 
     public static void main(String args[]) throws Exception {
         if (System.getProperty("os.name").startsWith("Windows")) {
@@ -48,11 +48,15 @@
         }
         Thread ss = new SensorServer(); ss.start();
         Thread ts = new TargetServer(); ts.start();
+
+	sensorPort = ((ServerThread)ss).server.getLocalPort();
+	targetPort = ((ServerThread)ts).server.getLocalPort();
+	    
         Thread sc = new SensorClient(); sc.start();
         Thread tc = new TargetClient(); tc.start();
 
         while(acceptCount < maxAcceptCount && !failed) {
-            Thread.yield();
+            Thread.sleep(10);
         }
         keepGoing = false;
         try {
@@ -66,11 +70,8 @@
                                        + acceptCount + "> times of accept!");
     }
 
-
-    static class SensorServer extends ThreadEx {
+    static class SensorServer extends ServerThread {
         public void runEx() throws Exception {
-            ServerSocket server;
-            server = new ServerSocket(sensorPort);
             while(keepGoing) {
                 try {
                     final Socket s = server.accept();
@@ -80,7 +81,7 @@
                                 int c = s.getInputStream().read();
                                 if(c != -1) {
                                     // No data is ever written to the peer's socket!
-                                    System.out.println("Oops: read a character: "
+                                    System.err.println("Oops: read a character: "
                                                        + (char) c);
                                     failed = true;
                                 }
@@ -92,17 +93,14 @@
                         }
                     }.start();
                 } catch (IOException ex) {
-                    //ex.printStackTrace();
+                    System.err.println("Exception on sensor server " + ex.getMessage());
                 }
             }
         }
     }
 
-    static class TargetServer extends ThreadEx {
+    static class TargetServer extends ServerThread {
         public void runEx() throws Exception {
-
-            ServerSocket server;
-            server = new ServerSocket(targetPort);
             while (keepGoing) {
                 try {
                     final Socket s = server.accept();
@@ -127,7 +125,7 @@
                         }
                     }.start();
                 } catch (IOException ex) {
-                    //ex.printStackTrace();
+                    System.err.println("Exception on target server " + ex.getMessage());
                 }
             }
         }
@@ -142,19 +140,19 @@
                 try {
                     s = new Socket();
                     synchronized(this) {
-                        while(!wake) {
+                        while(!wake && keepGoing) {
                             try {
                                 wait();
                             } catch (InterruptedException ex) { }
                         }
+			wake = false;
                     }
-                    wake = false;
                     s.connect(new InetSocketAddress(host, sensorPort));
                     try {
                         Thread.sleep(10);
                     } catch (InterruptedException ex) { }
                 } catch (IOException ex) {
-                    System.out.println("Exception on sensor client " + ex.getMessage());
+                    System.err.println("Exception on sensor client " + ex.getMessage());
                 } finally {
                     if(s != null) {
                         try {
@@ -200,38 +198,60 @@
                                 }
                             } catch (IOException ex) {
                                 if(!(ex instanceof ClosedChannelException))
-                                    System.out.println("Exception in target client child "
+                                    System.err.println("Exception in target client child "
                                                        + ex.toString());
                             }
                         }
                     };
                     t.start();
-                    while(!ready)
-                        Thread.yield();
+                    while(!ready && keepGoing) {
+                        try {
+                            Thread.sleep(10);
+			} catch (InterruptedException ex) {}
+		    }
                     s.close();
                     SensorClient.wakeMe();
                     t.join();
                 } catch (IOException ex) {
-                     System.out.println("Exception in target client parent "
+                     System.err.println("Exception in target client parent "
                                         + ex.getMessage());
                 } catch (InterruptedException ex) {}
             }
         }
     }
 
-    static abstract class ThreadEx extends Thread {
+    static abstract class ServerThread extends Thread {
+        ServerSocket server;
+	public ServerThread() {
+	    super();
+	    try {
+                server = new ServerSocket(0);
+	    } catch (IOException ex) {
+                ex.printStackTrace();
+	    }
+	}
+
+        public void interrupt() {
+	    super.interrupt();
+	    if (server != null) {
+	        try {
+	            server.close();
+		} catch (IOException ex) {
+                    ex.printStackTrace();
+		}
+	    }
+	}
         public void run() {
             try {
                 runEx();
             } catch (Exception ex) {
-                ex.printStackTrace();
+	        ex.printStackTrace();
             }
         }
 
         abstract void runEx() throws Exception;
     }
 
-
     public static void closeIt(Socket s) {
         try {
             if(s != null)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/text/Bidi/Bug6665028.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6665028
+ * @summary verify that the memory corruption doesn't happen. Note
+ * that this test case fails without the fix in some different ways,
+ * including timeout, due to the memory corruption.
+ * @build Bug6665028
+ * @run main/othervm/timeout=60 -Xmx16m Bug6665028
+ */
+
+import java.awt.font.TextAttribute;
+import java.text.AttributedString;
+import java.text.Bidi;
+
+// test1() and test2() were derived from BidiEmbeddingTest.
+public class Bug6665028 {
+
+    private static boolean runrun = true;
+
+    private static class Test extends Thread {
+	public void run() {
+	    while (runrun) {
+		test1();
+		test2();
+	    }
+	}
+    }
+
+    public static void main(String[] args) {
+	Test[] tests = new Test[4];
+	for (int i = 0; i < tests.length; i++) {
+	    Test t = new Test();
+	    tests[i] = t;
+	    t.start();
+	}
+
+	try {
+	    Thread.sleep(45000);
+	} catch (InterruptedException e) {
+	}
+
+	runrun = false;
+
+	for (int i = 0; i < tests.length; i++) {
+	    try {
+		tests[i].join();
+	    } catch (InterruptedException e) {
+	    }
+	}
+    }
+
+    static String target;
+    static {
+	String s = "A Bidi object provides information on the bidirectional reordering of the text used to create it. This is required, for example, to properly display Arabic or Hebrew text. ";
+	StringBuilder sb = new StringBuilder();
+	for (int i = 0; i < 1000; i++) {
+	    sb.append(s);
+	}
+	target = sb.toString();
+    }
+
+    static void test1() {
+	String str = "If this text is >" + target + "< the test passed.";
+	int start = str.indexOf(target);
+	int limit = start + target.length();
+
+	AttributedString astr = new AttributedString(str);
+	astr.addAttribute(TextAttribute.BIDI_EMBEDDING,
+			 new Integer(-1),
+			 start,
+			 limit);
+
+	Bidi bidi = new Bidi(astr.getIterator());
+
+	byte[] embs = new byte[str.length() + 3];
+	for (int i = start + 1; i < limit + 1; ++i) {
+	    embs[i] = -1;
+	}
+
+	Bidi bidi2 = new Bidi(str.toCharArray(), 0, embs, 1, str.length(), Bidi.DIRECTION_DEFAULT_LEFT_TO_RIGHT);
+	if (bidi.getRunCount() != 3 || bidi2.getRunCount() != 3) {
+	    throw new Error("Bidi run count incorrect");
+	}
+    }
+    
+    static void test2() {
+	String str = "If this text is >" + target + "< the test passed.";
+	int length = str.length();
+	int start = str.indexOf(target);
+	int limit = start + target.length();
+
+	AttributedString astr = new AttributedString(str);
+	astr.addAttribute(TextAttribute.RUN_DIRECTION, TextAttribute.RUN_DIRECTION_RTL);
+	
+	astr.addAttribute(TextAttribute.BIDI_EMBEDDING,
+			 new Integer(-3),
+			 start,
+			 limit);
+
+	Bidi bidi = new Bidi(astr.getIterator());
+
+	if (bidi.getRunCount() != 6) { // runs of spaces and angles at embedding bound,s and final period, each get level 1
+	    throw new Error("Bidi embedding processing failed");
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/LegacyIntrospectorTest.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6316460
+ * @summary Test that the legacy com.sun.management.jmx.Introspector
+ * methods work.
+ * @author Eamonn McManus
+ * @run clean LegacyIntrospectorTest
+ * @run build LegacyIntrospectorTest
+ * @run main LegacyIntrospectorTest
+ */
+
+import javax.management.*;
+import com.sun.management.jmx.*;
+
+public class LegacyIntrospectorTest {
+    public static interface TestMBean {
+        public int getWhatever();
+    }
+    public static class Test implements TestMBean {
+        public int getWhatever() {return 0;}
+    }
+
+    @SuppressWarnings("deprecation")
+    public static void main(String[] args) throws Exception {
+        MBeanInfo mbi = Introspector.testCompliance(Test.class);
+        MBeanAttributeInfo mbai = mbi.getAttributes()[0];
+        if (!mbai.getName().equals("Whatever"))
+            throw new Exception("Wrong attribute name: " + mbai.getName());
+        Class c = Introspector.getMBeanInterface(Test.class);
+        if (c != TestMBean.class)
+            throw new Exception("Wrong interface: " + c);
+
+        MBeanServer mbs1 = new MBeanServerImpl();
+        if (!mbs1.getDefaultDomain().equals("DefaultDomain"))
+            throw new Exception("Wrong default domain: " + mbs1.getDefaultDomain());
+
+        MBeanServer mbs2 = new MBeanServerImpl("Foo");
+        if (!mbs2.getDefaultDomain().equals("Foo"))
+            throw new Exception("Wrong default domain: " + mbs2.getDefaultDomain());
+
+        ObjectName delegateName =
+            new ObjectName("JMImplementation:type=MBeanServerDelegate");
+        MBeanInfo delegateInfo = mbs2.getMBeanInfo(delegateName);
+        MBeanInfo refDelegateInfo =
+            MBeanServerFactory.newMBeanServer().getMBeanInfo(delegateName);
+        if (!delegateInfo.equals(refDelegateInfo))
+            throw new Exception("Wrong delegate info from MBeanServerImpl: " +
+                                delegateInfo);
+
+        System.out.println("TEST PASSED");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/LocalOnlyTest.java	Thu Jul 10 00:00:00 2008 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6685178
+ * @summary Sanity check for local only option. In order to fully test this
+ *          new local only option two different machines would be required.
+ * @author Luis-Miguel Alventosa
+ * @run main/othervm LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote.local.only=true LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote.local.only=false LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=true LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=true LocalOnlyTest
+ * @run main/othervm -Dcom.sun.management.jmxremote.port=0 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false LocalOnlyTest
+ */
+
+import java.io.*;
+import java.lang.management.*;
+import java.util.*;
+import javax.management.*;
+import javax.management.remote.*;
+import com.sun.tools.attach.*;
+
+public class LocalOnlyTest {
+
+    public static void main(String args[]) throws Exception {
+        RuntimeMXBean rt = ManagementFactory.getRuntimeMXBean();
+        String name = rt.getName();
+        System.out.println("name = " + name);
+        String vmid = name.substring(0, name.indexOf("@"));
+        System.out.println("vmid = " + vmid);
+        VirtualMachine vm = VirtualMachine.attach(vmid);
+        String addr = vm.getAgentProperties().getProperty(
+                "com.sun.management.jmxremote.localConnectorAddress");
+        System.out.println("connectorAddress = " + addr);
+        if (addr == null) {
+            // Normally in ${java.home}/jre/lib/management-agent.jar
+            // but might be in ${java.home}/lib in build environments.
+            String javaHome = System.getProperty("java.home");
+            String agent = javaHome + File.separator + "jre" + File.separator +
+                    "lib" + File.separator + "management-agent.jar";
+            File f = new File(agent);
+            if (!f.exists()) {
+                agent = javaHome + File.separator + "lib" + File.separator +
+                        "management-agent.jar";
+                f = new File(agent);
+                if (!f.exists()) {
+                    throw new IOException("Management agent not found");
+                }
+            }
+            agent = f.getCanonicalPath();
+            try {
+                vm.loadAgent(agent, "com.sun.management.jmxremote");
+            } catch (AgentLoadException x) {
+                IOException ioe = new IOException(x.getMessage());
+                ioe.initCause(x);
+                throw ioe;
+            } catch (AgentInitializationException x) {
+                IOException ioe = new IOException(x.getMessage());
+                ioe.initCause(x);
+                throw ioe;
+            }
+            addr = vm.getAgentProperties().getProperty(
+                    "com.sun.management.jmxremote.localConnectorAddress");
+            System.out.println("connectorAddress (after loading agent) = " + addr);
+        }
+        vm.detach();
+        JMXServiceURL url = new JMXServiceURL(addr);
+        JMXConnector c = JMXConnectorFactory.connect(url);
+        System.out.println("connectionId  = " + c.getConnectionId());
+        System.out.println("Bye! Bye!");
+    }
+}
--- a/jdk/test/sun/net/www/http/ChunkedInputStream/test.txt	Fri May 30 00:00:00 2008 +0200
+++ b/jdk/test/sun/net/www/http/ChunkedInputStream/test.txt	Thu Jul 10 00:00:00 2008 +0200
@@ -1,2 +1,2 @@
-Fo`kMsMr*sth,dr2oD]eg<N\U4KGXn2VQ,&'!;AW&I["@nZQJWPG$PpAl;1AZ@R:DZ4;<,C-&1H7ZAjAq7LN`NV[,YDa^JKW_!oW6>=tA9q;%*^5$1[C24!O=7p0LB8c6EQ:bpii++fSJsNl3$mN#K[2eL#%d>c<39pV55VfO? t5a5 >+g-X9Yc=es5sI-ts)A9R5TqE?/<M.C8Zl  ^n"s`BDQp*W@oVW;]I'.h/b1:4!=.W%/01LcYF7=Um1(.GNWiH:Kp?Ch12Bg[5M`,TTE5TN\pba^I;oM2Z<O9%>*KqR@#RqN\;Cb99`H0d5^K*=fJ<]%Sd>i1hpA>313bbb#MCtA</sM^aXko^.Z7+VJ+(EYJgJ;j*\%5@13(Wd^;PcjC44A  I$8,VM>Eg2T*ancMc.8]W(7%'g.#VpQC!2AZ(0oW12mIhnJ-G]D;Q6OF(eon*,UL_H'UE 4Y? 1?_,2ia$K^X?R  hhS3!R5BC,T<ZN5!YZd6fQIR#P5G9=')C%:&VSLdN^\Q=(FarUg3XE_^O&Pgd`)M[,?JMA(tc@C?lCJElM>>@#rs1 gF*lPf8,*cCi:nAaE%*,qP_ofK<pL[$Mk;2G/Yp+/G1pr\l^!M.q<kd)1"Vlkr(fg;1^t-eBC0# -tR@1_oAY#7OSHnE=pt A/h_K[T[d[A-EmPnXA5VV2dAf(\"gAR$FA%$4@ TTG_O?MHmO[);^]F##V68*QQ'&B%p<rfl-LXiD[Oi3s;l6aCfB$UP,?TEArTRhX@<"d8%#K%`]$V=3-:kb%mdJi8CW_5"V/'4\V6cVn(YGRK[4odBH!?#G1^%*8Li_!UI[(4t4WjSQ6>]hZ@>cQ?A;,EH7fU]GR2p25#UA$.oE5/ETshg=9Vk_;RC#<^nK?)PKL(YCWdtBChB*T>[%;/@Rq[Alea)>Ib^QrKHG2KcbE0mD&/'eS*tX&\8+U,Q#Zm_`8?%In$FLme]D% ()6T<AlGK&rH3GdpT73OclHAtINAkXo9otK-O+;eAd>Es4q.E.\S$= 7iO_5W?K\UA2:WSgk?-p@=SQU#E/1!4.@--8IW]kLr"j;$TCUr,R,s7OlD-(o#dlEef9VK?'53Xq]/3-s!3B?Z&#3Ok&d'a*X1TRs$(?O`DTmX3mPX,>=,![AO/gEO^,W^00>Aq\)M=a3:U`AVleR6-Y[4qdj1Nl,gEDi']t&><6n0#)'Z0Ci.pZY$d1A4E?FrX9Blka%LHWMd ilA@#'i'db3# ]+Mf4VRQn6'nXg#E)I(8<5I&(lT5Y$1s.5[0tYd]IbLkgGlt%?^MHq!k!h'FP18>%"oqn+V?WX<FN2Q /=3aW@ri7A8]i.)<pP=;OJ(Z)@(kk2Yt5_?/'hVjq&n'-sU`1& BJfe9*!JgT84l]Po+=(geID#F=d-($??n#64nRW<AAK%Zd$#23 k]M-`N#T9dnAkX-$WAJJ"GjGp($L]#7h9WMkYN3Z:#eW-.0F=5CeT(K$afW!t/NcVDa*SIRV`ASWk#UnIfb8Q.&pG\)7]E\abi^ )"W*e4ab\s"V@D%?Hp`?sB,We. -tdprb$B&>AK,6JP\KYb5jIJZAG 7F"0a<l?+^R6iPro=S`r-VWEcYRA'-*)?Hn;sK<dN;B2ZRZ&EsB20,MGK34ODqIA<^D(#*Ahcm]XRb_7-jtt0AegK\`A+pX5l dcLk(K!!FcE-9CcI.`M5%N(X$)lMOAaX;8Aei1;3MS<c#/eKhS]\\X;7&aoO:S$^efs9po;[JAY2LrVMALKAXAoY)jW2+n6'?#,UrD.3Y);"?JBb_5B7T]o/.dZc\qaF5-] ADXZJM:f%F&bDZ8dBK;"iW]_U_?TeC+[*a.o[MR.$G/7^Q\fRhVa BfIhNA&Z]=;<#mFl<G$/V=#WI\cG0;+g e-*7cAg<UIci"i+If;"PRrU&C;4poA#%*GfQ>'"A"g<61lB:'^;idCr*82Z>MEOCeHqH^Se6;OgKSWR]"Kji7'1:VI)AC"nA7mhWM*okf"4,G7hm:c6B&$3CM.8fIbb[kPX',j^&K6"IoHXPQgY>@E=HE0-$10tpQ mXol_g,-rmo11C4F3b8t;@JINZ.t#TT7eG.+CjQ&NN)IqI3hE6EF'h)!f6spqV,fm4`H<PRgV5N*r3r2%sSB.9g3R,SAqV8XY<n5WR\)2)2GA H)bCIH2iNTJFY_lg%KBX22=lb66^K?_K<FCbElA(IEaX`H',\"!Z9l][*XjKscs(;`\fgDRPrVO1.1N%NnWgl;I^B__B/-Zs%!K(5jV'A!$">irb'7+pr8Y,NqR^eF_23mt@C3@MGAHm0d;3rY&+tsK(BK30:V]"gTpI=$ms8j*+qddro#A(Y64/i!F2PA3<9/WQX?l6QV^V&)m!C]F$@ 468?JD8p``2c.;]3mkp)Bl'X2PpYSi+[t<UF\X)=EGfr K?A/;Dgq)qD4.4c)7Y&PKg>Es^%2h ,)YbjfMA5:dYE'1)rb]]/j1?:Iq37N8f.>+UQ "f5qFFYloKPQ`I#0ZFLrgQ1WQ\:)L-6\$Q1UDgI!d,_#),YE90K^EY0*0saQnl48<1`(@3L%LshoA?:5Gd0,6/b0!pIibT2UW9c()EH0.+>aoE%`]e[:.A!9^rMan?\peDIlNkjaJiX-=gYcFoXXbTYD8+Sp8US^t0cBf3@I?<7&f 2%n9!]t9rF_flN_U)74!ghb.I!'D4n5dim##5j:?GPH_3Q;gB$j'qNk[H,%n6dc0aBl&>PN-X3J.[pNK 2S'oEm_dsA1&+b`$3h32%m)"QNiJIWX9%*49_)I&ARkIm:gM(Vh!$bI1iSC/;/efNr_`sWbT'>T;fNIJ<%NW0%A)]npAdI>\KaA[.G-8An8&VN6)A$o4,@31\];&k4*=*?pasKksN1=1l-ISJEY/_`=U]j[Td-9;(OFh(IHp70H!2kN/9to//b/_ar&/Xe9CmaqX:`X,S\^A+AQes./s'F:2ZMY :m H+3XS)l35Y]AicKV"G?4XERT;gD?+<J[(S*sDO2A:?Dc6?!]qOVRIYF4bMiFBo]LVRGl:L0SGI!&i%Rq<%KXn8l<)B"OVtd?=)5)>)S.0?,8X=414C$hD`@?3"Sc/s>A[bFPR^]CnN8ml`[pD$q%M,aSCC$b$#D!JN=;^9VLl>P$8s).J7tC!^LQ,c4dPAoU,M7NmQk=90>$=:&_J;s?Y$/#I^h_`%2K$[^S[7f=Oa21<Q!o%eb5FXT:E'=\8k,(oaOF#76[i!T,B`i3",0)r[-8]tkf-ZUWdKr+Sf2dM',1-Pkn/V:p1=[ @a@rRgtt79k<Y"HK+;U;l-5*JOGJ: IWH[>sm+aM=G89g8RD:KQ)pRKLf'/>$ciA'Lr7+X'%1D+6hDh@8G#+B:/_"EaEc)VPU$kLC32rR-?HCm_QlA2Qlf[@n^K'OC7CDEFI]`;C5.EQ$V0,V.<E#;<.J8PiYa`M$FYCP[8$3Dif8K'RSc@r@MF XRPUqE?nmRhVE4D<^[%5D(^.>V.t4OQ_mqq37`53H)8rAGPldR>'1DEec?"2IGY,ane;V7C:K/__[:&<dboAG@@WqJZ:3<^.ffSXTgT(X./0T_"B06!]fejtX+?"dGC#nSP\JUSFU'mS22bI#WAp\83A2T(Mah,S`@56_B\r2.1Q9=f(-6K6YZ#Gf\;o,  7.cIAMP_(5X2O("&7fr`;lO2!5=W,8`9`s/6N!+6+A!PJfWK\A< XSr6gdpo=eE!e1jqMR"ptea0A+i[Qf<Y ,)YtQ4qA7e+#E6pcFs\c^_<f0?p9bUt .#?dSj*JeK,#2QE0&9/;dM6iN8/$K%=&i[%pcCmf(;`,.]qK;nG4UM2&k%eI;9$sf-XZBajKVLE==J>-Q(Y3DN39tKGiOML4ZJ/]jY*6K("f?j]d5Q`"(!a6^EnhMXs-4(YR2'J@A!hV_VYI.'P,/ct:aiY%I5X*@<<!f2$Fd[n#8H>Xt!%`[GkeOtZa[( XBpK2#?$1UiL2i!?t8SDQ]UBEW@5SN:$qlSg'CJ>p4G44h[U)U*4s.C'ieWRf:.VF]R(Q.iRPRAi0HUFmR8GAtnR1D&03T):Hpn+RlJa>:[U<*83'R<ZrVPX-mARst:2b;nm:8`R ah-e5GLA0Go'>8Fr%W$]?l)KANM[Ttj gKAfib:.oo,D?jMTW<3DIFMR\io*NBBA$.9'8A6g#(FsamZsV[>Ml`Y&<W"Tq)i8'ROHA9<4@#a56nIM,ME'>LJ18>52+]9pLqoAIWG##HMS2`^SX$'N0dP/)7*DVh;<llE__mo^GAHFXh+,nhg[,\S`oWd!dH+iUA)Cg@qlT jQ?8()W2`0RA9_i Y;!EBdA$_[IX'ERYmL[MkeMnHN0 R"8Nhn7>%)Hh\ e7F@VP61nAQm%^$@;fs\@mrNC5=Or32)c[O6G3#OrFN>k;m0oPe/]0!.i=5Qp+Is@bJ<-cLh_.Ia91f6M+7l;+\mH7V$Ai"4mAp<H ?)6O[-8rE,S6O8'mV??t@ZF^mZ@@"eZhf6M(b3j32;E*13J*rZY9jWB=Zn[(?GU-9>-#Y(jDKCL:4Vr!h#<idLO<paCgYJdN^6rIJk_[]])O!JW%n`EiNq^ZUXL#,))es;M*=%h'#*Mlod2%-Db)MM 0OJMn95,+N]`l#5MM/:hb8V0R/n[)D3WG#@^.(#o%be-5gJH-Fs"`2VH 5"Aj/cV#ZXCH:9ko0jWL:<B+)"J`.l<8K*)-A:QX/($milWkP1L1aQR%"0GU-_".E5"J>k8<CSPU?ieVSFh<(F niAmnHk!l$\sf_=jraa7AK2de2AF2>R"*n88`WB?N)/o9KG\8A]PmSnj,=q=h!%(X+*%Z_/ApSK0`.L;*%@G22NlmG='pP%,JBl$WZ:AS)rlaK/^(J+B^6fW*E C37[ae^A]L@g$;/Ho)o)1:W6q><Q\E7s9(h`c'OTETn:!q`s_K2),-SGXf+!'fgMAqN9/N3,ZS`+`VOd9oT'@B@5ZB<Pk>GbC42!!oDY5#cMQmK3-<)(m#=s%&K37[:CU-hm->V"/AM\ 2BfkNtlILl`fPWRG^+d_9rcNQFckrMM.!3jP2V<b(:QZiAo6XdK KD5-f95M&=Y$'1hV=]F?b6E"^W.I2<7kgnUQlj;YQ'W8NFe?Pc%[Z^BEnel*gUJ:gp`7lGR<sWo*:L^,I@i9KoZ#DK_R/P.QZ(FLN!RO<DH7qY33s88-V/:nIV`_e;!=EW,M.@b!K8$g(:&dKd 1+ghHQ_)#L(]BR=Qg"d1(IaaPU#L=m;U#U;_cR6@A4CTAWnRrdMHjg%2blsYFa!,V9q^;*o"9e]j/-fg.; I@=hri190<\Ld;U^_L"G%ZtjfQor;mA/V<SE%9 DK;JB9^>fg5_YboSY$].O r)#c8_"RFR#WEt(dQCYF8h;ngfPe^Ero9^bWGha"p"J]+f.<>A`G s^Xs9s%I&aF3k(BC@WZ"J9-425-K3884cC_#0Z2 >%o<rip@)O#%A62g?fTsOAa4a36q&D3AJ!JkoSjsXE1#n12,,+n* ,d(o'Z+`;2,RCd]9[%@hTE9r8I-HJOJ$P6':P0,A<mgI%NSe 5tm=.l9eXj9T'I%al,J9A(=rRomPh3n@OVjk>&UIrn.]!F8I#*Th=17cHo>^;_8dB:>NMm'XX<sZM8$3UsY(sJ-An`L0_.!/GhED.&$37=>@beT#@YdX3DFir7"Q'tVgC2$3="Ke9<0Z/i"]":tD-/nfkbdT_X/f)ka]=.l!c?IXTW,9!34IK/'*,/.8OA`8aoXCBI)SGDZdi3b?a`%bI;nNAAfg5KXSC8NdCa(!E:T*fIo2V)8Q;j q<42ACAa.4[Y@<OX&G&JJ[bW[3;Akj&&e!.;;=)abrA2*`5TQlbpi!?P,f_eV#Tt G!rd bi-Rf'-p%U@V7Q\/I?J+mR0m/p6VW4g26;7BUG<N[UJ=U9+@IQ:rA.O&(=O#KK2dj46OP&TFFE+h*8()fLTP[2OW qr=`X;/tCWh905f8f52;D?m-BG4h=I(A]L(K?G&YK'0eI=%:%%>fQscTe-Af]R9Z!B&f@3T2^G+NfGDgHPP!J,Qi5oCC\$B@I3Eg/6D3&MOfs$K9V),ESse*!h_BL_h-mA_19@P&s3i_0iHT+8#"? A)te`srfDN:Qjr =9Q5@m&S8U*eG`k+UC@Op]SVZp7bRqca5TaQ@_g,K"O>Mk8Tkh6K%[TeG=k1P'^k4`43Kp'N+A3+'>e M>-a!M@QEPf>BY.M^D#@!8RAn&" lZp*=gJD#>l.44)c8kJ0EjKn@q4]@Y"mKH\t@=Q!ISeN@[A=q`kl;K32M1r$LV+mb_ni\;IE,6>d$t)B ABH]7&-OK7"('Usf4<rZ=KP(HgBg&TC*^@Z$<'X5<C=+P=iUk1OUaFWGOg<I_Ac$@I-'EcO]6eGc.GF5ZgC8Y jRT@J:3/#*_>U>;ZrgSANg+q7P8tFk0)r%3<-aN*%<p`FYk>`<IX2bS/j42rGs'?VYO0`OQgi8T`, r'(&F7Y<g4oA"(o?:r.*(e6<hBRF( '"$j+Ci Xpr#5Iee>ZUL-14<T&jITd+]Vlgb4/,'YE&ftJ:Qe1+E&F;>2$\*VD79cs,gWm0n+DS7bcA,c14[CZQn]kb/-$nM,K;F";E%4X[R#GGd<f86&...O.Mb+V3jBs5@hK]OH/lW.[;O/J'sa]E4'^eHRV?!l@QpA/];D2c3j\<qo%GhV=[Zb3&I;=(-;)O9m*P7'-k/Kp:NEm\OaD A\ZA[0A5r]:" %S:V%Mk`0rTs8t-U^gGBcn!om 8^-6V&T;$>pX"!h`j=A9_%pt4mZ]LJoOMh#$*nX57JktJ5HI?#ne/qIMd:?F9:q*_UG%ILCdH>fQ\f#>Y7OP(+"C'HD9a&F`'6ir+QkiB`,/EAT'IaBH$'gIAGL>;RtSL"1gO>XeX.L 1SZ+A]31S4W9T>4EJSpPk<4#("#CaOV>>iGftc7?5[?(T^qc:kl2I'#.t^6,`H4W!DfMI9oGt$p0>5f.Z>JO`^Be%q=/\eg]7MaOY:2_,]-,b!A;;_OR A5P.n%Z7YLIe^)1_$N$?&>oA6$59qS8"@VbD8bV:ON"!]`jC@4n:6eDT)3E=(orMJ<ft(p).*n&m(@gO<&[R1jce$dE08i+I=@4P?/E&(bWUdCBsK;OmWDah$02GZfA?,bY7&S=OS1LU>r+U/U-E%h*J> ]QinJS"Z`-9QP2rBF?g#8m PlBDJg^)p'Y4bRk OZ\`0<"p0#`Fq</t8\@flWcEKrMGqD-Y6;3'C<B:6'/BGq9/On3bqOa">LDRa_Md",AR>_7tqgAI6q>F\ rUP2h6P5Lf!WmaGeslT$$:km:"^b98>B@[58%Vk8o[4,3`i<A:q'ZH_pY%"Uo'`nA`#.43cb+C9`m)k1!%m`%&mseOt9o+e2ctA0Xb8dWXkl.0F'&Ws"&JQZjC1QUQf.DqldZ3oGQ+pSCX4l +Al : eAjU?!67ReeTYltifnT*HmKGP&t$Js=8ZnCR/*m-r_j5Ydp3Yr. M0aD?'P4lkVs=?d(*<BdY]jr[SC$jp_YS)j2F=AR*8^m2hgOQOSV_^JjP#sX/\A+-aQhT>-j`:lG Jp3Z@RD+o"K;Oo`cgPBOm:XS[SO/hl\%V"K%rXTaOdA?!`KL0[jil< IE9'PaXf@/tA#eT'SBZ]es'ljk^/f?i^b`k`CeqsgEah1N^_qKFOQ:V,nH;?rWTWAh8@J)AJ-fdM.Ub'>9`Ht>[4A\. HEF2YA9)_X3L^H[B`)dO UYDPi]b&C`-AD`ettad@A#nG>L4c\Wcp"a%d1Bt4"atAn_#%3>VCJq$l$>O^!?$WB17E,NMQI9hqOM,Kl#0QC)5_M%B2E"K7Dt9XK[s@_HW( Xp8-1+,k\hs [i?3?4XCQ9R@I1c,D4?]8FU17BbSEg^J]H'(3&Hist50)n$_k1ZX=$.[:O6<T_<j:`*J"-r,6PMD[9MCs;(Yq<qrK<Kq2 J>R_<AA$0bA>rL`V#&"G<PcUU"nGF[?"W"J%&'nZ3tMD,D?pgc7A[?SXo%+^=?0?FaG6ec"!m0<,H.U\iP;\JS/:dXZGG5nH)-IHaoe&IakR!hcp"nK]q@t7`#Z-1UKD.](XQ4EW%OCAFPfP)%cOW6(#1fA2hleLsX"6qIZI/PkPB,0TlRj+XZg1,g6)<;R6S)`lP]B&`:YB""-A=\O-PW7ZQ5U=IgKgI73V""LsK$)r@T[dQOqtq-7)1MNFR\Rg3hUS*XK"i#A1MPRbhNF),"n!G4AVFnsDl/,!rMD'IHqp@^Aq4TA5'gcKQ>Pi<GU 8>(Zk4\Tk?UAZ@,gt)S#c&n/KSYnFGZjs^cACm;+eP6F^)MAGhoqV4`@1%UMmfNba+"& 0sY!5$N>XYCnoO9^FI6'Y >U,i^S$3>sW3#itq3RnU@rgE1^8\UTrjTcUHbl$CFC%)UY[P:8'M'a6^1O4Y!kgi@n8:%j^P-cslBH*r,-Q"Psn4bKbHHAUVLl%F_fB\P<sD$^O&VU,5Xf';b#cibEC64s c(Wl+T+UE&N,[r6Z`Nk>h*jme`BI1EhI<tPT8'd=nFNSC\#76?:Dg-hVE!L7pL?']SHj@mFc=fH>TO9_gA%]A"i<37)\jY=sD8sYN^9XFA/Ml<+seGea<.6D^$UC[=X-4`tk@fI<aWHN,m37@@E2"LW<b *\l-lL,4OFomrX8JB7`Z<r=tOtOtBdE?[FQ2%g_I.@Ucq$@saZ*AA )qZ,[^(UCZYG*2A $&* (UTA'26U@"_(=Ze]H?i0U3W'K(b$s=&+V+[eBthtG:"E%4^;;jJR2q'1>XG]%M_h:kVC\&C#1j,`E;2[CP_;_,SHb+MHJ][=@?Z\J[!ciZMSC=8T_P^+7+4 #0aMJB#M7+J9Y(TrprMRVhqp%6n6ph[#A1N=8i>Md4<b+GoT'>mPMB$b#AdB5bdamqKn6.so 1O2dscP,`V1#sAjYn-$).Ao3moshGH`Y^-a>1T?/^VeV aR(MfbU*_)lD<ARlksCHYS6i 0q>iE%8OlO?pr$ZfBJj5#^-GX'h(lCVdm<9)q".PI$+*5j!p_'3#>\Il_VpFG6Zjia`Dtp+IWhr@EH#]l0o\`js?_);^=90%PE(m]hA-Vm/r)\W9ENd*Edn+NM,G^,U/n;tA^+<A5Y)VTN+$7=+2ij&=^i_/.T,gT^.CdD1Fs5d+qNl1Z2T*20$cnAc:sB^.?$+m(IlJae \18$h,GVofc!rdX asfdnd4&SOrds;@9][aJ.3h0=t`NnA(fim`UiZ&H '=Ic!`JiOWM-#T6QXPDcec3!J;+/UBa%!onsq92N4A':K7*FnRl=J6H(bRmHG)clO6e2CEd6,GgGO_Q8n!>RQIGfiB9s5o6`RjM[ALmTXqNm@Z:O<6NTbU`)NOr.a:gm^b_XYn-Va0`;P? RCFlYsq/5Pr%$G?r^AZAE&/d*X7AYM\AC,Mes7G -Hb0B\BfX6kcUaJ_5[W1+lp6<;T$WU=C&\hg6A^NeR%bIWE6ZjlN\:k&Kb+<V9boOA3We'Pp+PkF'h5^NrL(PC&SIg%Y$%fDpJA1Ol[+q!_>B7A6N4>?q&C-pLlqE@c)j/Ml\i'J'\/N4((UnMeLVG-?rc?_4]>TAn6!eU_:tUA?OYrAJ[:n>nrn>tOl]L,L3tb%q1"TKD_Ggo :+r<+/L<-QrHM<=)i1La%Yj<M[$U\-a6&PRZ>*#]#`akcXI$cXUbL:=!nNd4$]flE;,Y4(i51saE!5.n97EkgA`IQUb$1s_<[*SpA1j/,IYK=$^.'*J;^U1Aa:r\*[5'BfPm5i\R:Y5N7XT*fJ;m"f<-*_ ePoqPlR7d4nX0[ZP'7CSd8!faj)#/6e[R+!^]L[R:N:TNV!(Kr]OV]a<fSRWGjM;1A!UfQY! C:.jXD2k)AUFH55Z/Te`=;5\Gr'3UgmS0.MhbHXAV;hAcl1a)Zj)t]QG+:J3nm8^\)kSha(@A;OIiY[%%8ieU-cE,_"JR=4l]Lliip./\p7dYXRt\R1@5NG:lQi1nFOXUC4(MW*b+,o\MmaV.BBKf5E5k!+5tih6q+FeghS53%/T*4_R^PLV*EhW0>`% 'I-L hGX.orUtGE^39%Nio,O9MZ;+bHD?BJDBPVAk'SV%5rFKf"?[RX`W\t+Dp$)0NZ_IgY*9I"+GSj3NL[k%HI-fm9A]*9\;\>CTdiC02j0G04t_2C)XN&a6!NCi&_[W*E+K*."oe6R:Oj2/4rU6PtGm9X]s>ho)^1<44a0AT%ELqE/-UKgS#AB$kVBmie4$1Y`0JHGlRa#Xc:]60EN9KE:of(H;ElD[-b]C6hOqKdd#&8/Ct2<^WG->k1N._J]6)TUC2mWRXrPD"Y8'_,rqThCrN+A_oEMMkM5-rY2:3Xl1 @J)D=WVEo)paNT7\MYaD^:\WF6(/m:-oEQ98:]mn#U2rTqm7W07fcC6V&pFWgZ!A^-Ri>AAY?!!sY[:h8OB'o6t?3_]rM4^IfRmA$'mPB<X2,@j62V_BkPrr/6H*4NiF23S%(,EO!Q %$RLjP5X& dHpAUB h>9RjB34sA:CJ(R;lN6,kj1<ao`E3p<h7J&^s-p8+kdahR+Y@q*=<`rl6FFZjEh^OG5d9>[LNKFk4a!+V_Rh;;O><H9'3C`YRV`s4%/?%b_%E3?f0*`?[>&;)P/*^g?AAiJ`@*k?1A%p<4%9L2R:C!fReCA[f#T1C6sYjI_D/H`IV@*N6LX'`m>\qeb %'3.)%;s#s!6/B#8dd`5di,iDPHo7MQ$AV=J+V0:(\<8fZa%E@Z7)"ZlWG4;b.0*S,<"K9#CihF83rBU(&mA&5EDV,'WJ=3NXeAW3@.j2/:!+an"I%3q(9(kqZgY9h]q,VK&![P9;J=D07JI_\6+/:21[RB<D#^-Y-KhIW\TX_dUF=AfD@otfd$h))fGYlq#h\<lEMa!SAs_@+SZ`r;8E0m5UMYmKlI''BkpF:iLERQ,?tXamgrf/;%Hr^Mg0l1ZPn[q4cFoOX'\=>q#4%?Fci'2V,<%6krSb@]jEo:YMGB7P87$W;76_U"nHlgO2 o>'[KdHeIl+n@'5[+Bd.^:\Jt&\Ap\RO2Fn5C&`omaZk:sGJj&_SIO0P-Cd;G3#j(I.Z=NCqc 2%(:[0hN1FV89i'a+ed49r,f\kNa@_KE*@ZZP\GFNRNQ;"+ghd]$LgM%3U05!U-$#I2.6 GM.Cq7P&WDYj$qd`V_755b9$K7,9(Sf=6>@<R(]Q=)V9p>J9pbr+RAf>A74AV_E>Fg]^+-0UtQi_m3+rkfFFEr'<%iHE/4B7N'sRWoRIc*U_qfZ(pFqp,^'0-ja;tcTHL5:+gJPb_qrZl.X(/0TeXTVZ"4AR/'lPAsqA<$@Ej%/0XV$:][.2mhWZ]lgQ?eD8q:t>_himc#`.>6[$mMSG)7CZBZ\e!QI7U=HDoP,3)B5C7Ulm`8l&?97]9bV$) c*11'-:+% f_[-8hncgs>Na[J (jUgspZ80?Ia_'AV;n/VQ0I`\QC$>`:PG6t >1!Z%s\a(FNgB;;HbsFWlOV9<aAs^'\eZZJQfc>3M8[Ut%f/AT2]4a@fo=&HiQ$Kkle-FYl a@C8F)*S;lU"VkdR9\LfU/TT!@.L'+ZhI,!?G3A!#@-h)^!B?)c>:O8cA4gUgeE#kH'\>E:`Rn#i!@2,*)H+HVeRB,cATD8U;RsNOXr*M;O+NTMJGe<Db!OI6eErYAcU4/Z$[Ce_ZE.)Mrc=8:OS%hl.!c[67W8cM1Z4Ge.6/3CFfjm?$6!S<A96Ork]-0/AZn!U)@-0kt%]CT0`F@B.b9`3,8o"sRTPW;sWU'Sl@^FZ$^=RcfT>6$J,BI9'cg'=ei>U`gN41oN#SSV`o[8aOLPjsb0pL^G#MnmAgsb=(`-0T)4mP2A43]F!Uh\hA*V6 9#@Za_'IE2Ai;qk$JQY5>o;L)\]:h7Z)^G7#b'r-KqtTi'dWAC^g,"^i)abIli*HV@7rW#;[H.^HAVDU0)J:8sn2XK+LR._$[Vr,4Eb/7LT^MBL3gcWI7E?sZRn0YPA.\N%UqZT"H:5"Ha +4&mLinhZ%SHpL<hhc.<+2Aihamn$t14&e;M=G6)=c6hP,D:eK>CjG@EpaTt]I+&VgLL6s%+epH56Rq<iMh6<oRS59M$sl:-VHg7r>LE_Js\!*V6EAJ<m@[g2W`/]fs@W3-.LWqIB=:jc1,1YB(:0]qBBrVa;b(D5%kqiYA0p8l<V1oTY<-S&=lmsbAiZ;jFdCEU`lA7O<?aG'W?CH[GC"TB3lPt1#">4"tQerAf'c/]icOeFc]>qJahlBP61.6Zn1e:I5 r78,#,F /3<;SFor=OJLpMlGrc$]/91SAq6(c[(Fle]DE#!/r\CdaCl)$0R$4B-4bm4dX ]0#T,5#9#(`J,Aj?&_%EcpA7_aQJCpFA*F[0r;.q*f0>3$$!_'tRVnR?Q$Q"0XT9?Tq+c_9!_^8eph%AR25K>)6T%F01e/>&b2f]l+nAgmQg8kHb psX3`)5MpE1O.Q!"DT'`;7A-tWqW@P20f$$T/a>PebHtn1!qZT'&JHqr[&'* =52"&7dpe?g.$o%-kKF7q,O0.i?lc698?&86,"NdI3_=M]nkAfAt(7"*tEfQ=-K#I<q67aDF@AD3&RHa4,3Bc[e]FUa>I_0<o0q@cqtbSi'aJ8b6oEkG J=S(Ttr#a2]iN ?&EdQn\N8?m.0f$c2s29AXnfRrD0YYe=h@Q@ZjCe-a08LEl`k96Pm;B-<tbV"TjZ2\.:n<A*IAH*]W6C#lBaq,@epQ^EPI_"<RQ(7m*tZ3gfRVdE2[rolYp (b:G1:C(l@+s2(JL8pEFNE,;km0RU)GA/:St7D"n]JriFr`1*e ]VIpQXV":%co r[GN6H@-:9J5_+['9e5=d,XAB;2fAn.MM5/W!RVm'L?3EHh8/T];)\7jY3Wid<)fCaM=*.kGVRA@W1mb+q&dFAjlpU+nNr=\N@N8j4bA88ZKcfaP7sP%?4@e9)@p`oa2LKVmUKTm%Z 1?4l.rE*WsK5=B&!>q:N.0:K]80%4=JdT[F0n":o%VE& 7;;]E)'rAS_Nc-$P\NppVegCj</=2bL4E>TY>\lcF!%a:rq;9ndd'A:RY&IhG`p5>>Hj^/Wpn)<!^EIH^`@AFS3WL3P>7-f6$8A)=>0+* 7$4o63)&!i-YA,0;t\MkD(AgZah_<[k0o"0]af<(rDd%XfeBU#W/^QS!LTO[PV+8,<A(+P-d42rItI3#eVmFj&F7^as+NJ-RDht  (2FRGbRSQ_R758OHQsFWg`3FHh?jF.r31]^^`[>jY_N*bApB[$!`-QWWA#H->h<CZ`F8p.-B=Z=N-BO!^@@8$A.;" ^/3%Q<]?/b:+VlD`YsUmk":QAh/r;[7d+L/-_*/VN$`h8c"T/[ha@9 );p@U"m<k8[0ejHl^OiCYaZpLE5rnODn':*[M+/RP-GJ3%q8t X9Qp*>AJRlr$UQ<H43#THG3BsI)J0io;C<M:O5*r5SNQ&Z[@ F<G'-VtA?q)I,6hH&b4&g+OJ<\97!`N'/2(3BBpJ!\.&`@q4\^4H)+O=$sHgA#Gc]G='R<Dff"7aF+',VTNeSUi?bbj%FIk_DtiL9cK"DdmW1gr,KX>N(hAmmN\m!Y3R?nY'"`Rr4e))Ys@rQ6(FW9+m(8<6%1roR(^ERjQ>Aoab3a1MR=_]O/h4Irsl=W5+T3ZFSn`X0+r#O*iHD?bGj?I7m8IpjrFoa5J\97IJE66Ob[-4N_o,d-KP#P<rEf@]!AW"4o;D^Goel3A8a5;V^i)cCQ'4sJSm^kAM&`S8Ai!X/Agp3n3?5Ob/K7ojG_+#I&jY%Qr&k@`\`<[mF 0p_(Zi''$a//E?[a<-Wi:7Kl-Sk@N o'eCcBgHJ(ZU,(!e8,ffV6q\[[a0L5bK)\hefXm4A2s#<t6Ed)(<6K0)\7iq>mqB;G=fXB8#]1AL7.HQoXm-[$A\\CQb)f*TfEH1Q()dJ?f&qZlmRo;a%-LnqtW3e&5PgT5d;Has=F2_VI@'FrHm,WN?2 *"=U `K'P$PchrWcdt L92Kj4;kTH=#?H"cf<@iiXjA_QN^rj4qLV";XPD9j:bV01]`34N1\%DX/Ff@#XBI/Lo#c QCoJ\IZ$g(1KG2#(:XDi8A.P"d,A_68DjmdT!hT<G[=Z0H@%j]'jQbkp"q)+)g_:[AYDW,K'LPY:rM4t>.V&m?$9OAM3$5kn+,%0o>W\p<o"Ae_E^)e-oLT@Aa-acg7_9No=J;<@rA`?'!YGG8OG7D(M/H>IXT`^5!6<K>k%@p]Ybdg-7nI"A9V]]2SWb!JA!k)D#W8R2B'ALHClX$++inHhl,8AXH!U j.7%W"Z6tNSf7STULk#,b=c2Y`\M8=j>!L<n>A\i$qn8!`$El*4qXlSbfb3!aDY?2R%[1R5Ah"'$$j?8pp1qtA'Jl$%CW/KX#QcL%9a)['lmKB/(.BG]:TpH6$]M$P3\E,H=El.).V_g'G(SKG/>Z +7Sg  PKXjE]t+.WS^o8?G+9(9o@9@1c?LgS<$&?)tbb^'g(er+C2@fq_->mnAkE5cCn*<>AI/KAoGo>9TcH+h`Wd? FbbjTld6Hm+oYiT&XBq+Tb/Yf9BTIB^Ch`AZldmX'?0WT. @VSl&XcW:#(FW^.IAG(a&UF<A?aHQG"9sAEKhicer@J0`1<UJ5=."s:r-FqL+^:<&;JHr(L3T0ZR,>98DfaUc5>!o9$?$41o7OMdQN 'CCF=3n9,H-GV1:C2fre*/DfeAAgS<E.bQ^&4b7:#ChiO0/(Hq\S%DaH#T+7lYsIUS\"[Q60MRkTZpC29Uam&%?)2LniR"^$@&4Hta5=hQXj*M_EC.4DGJ0,V:>Cp#^OM0Us`WMg\KO4)#5VeCjJY-3Nn8Z+dM8HLr;&bU#`l<.J:+WdI9TALi7"Z.An&t-&SVX`XOY)D:7Cd+Ddfr!Y-0&jr9ie)OCg-)sqid!Q,>ghj*.<4]<aYpe8Z`Vad^(+]OgLt*-%P:?DMA?-;qR_g+>]ft=rY!g>i%M`] kX-bg;:*`c :*FpCB="6Cp?Ksn1E-<iQp4'(EO$[MdUB'LhkB*?DXotl1:)esp1#_CP/O7k@'eH,j5`?lltq,NR?Q3)K,]9^#>$6*nP"]JM1==QSeI5@A"1AJ/Z_F%\AC')E3ZqSM3L2.IfClYbSGOb?aeeqJU!UH_2PI2IVoJ6q7pYVa71dJ%G/foptEZbhC#'i^4tPXI0= KDT Y-TRaHabpCCf="Bi`+t-V#dP>j"+FJN/KL',;Gpj3Q5Vfn6i?8El?H4p'?A"h)A'K%Sm^r%a7-\YgE9pLcSV!=?p%(7TIdC,UJ?]b+L0LJ3PEHeXZTr].8CR?b;,t4!C'>Z&UEGNT$PlIQW6DSsF;WeM2&o=mUA>cAhf-i$qW*KB I)9.1Ae%^ICbAe2h7.Z]$UQ!@G,pCLD1J>:A#U>hg/fathk5@GnFm"/:HW)V\+\*c)m2Jk8DoKPOBc7]fSih46G/\rq0&rm#,G3J;E-*rDh sS= *C%f.NATZooQ.modqS#(%dHm;?a4d&b!XWgOmKTf"q9I -2%%q,8R4,J#$5gBfZTYMm,tq2SA+ifSo/r[#P]T<sPs5P<%KADoLC3t3T5l\d?-pNlf\80T4:jo?sq9f38r_%_-@PQ8+"U!Ab)\ LCp)RsPYNC`D.'j(FQrAA(hW2+LK)TB/#2e@CpI`![q 2=&b;kl8k6FWhGZ`.>^7eX0(.?F6`%@`NXKL=PX\?XR7=GQRsCYK 0Q\S/ZOS`W`[9W)X7V_(iTHfR:`>AF:g>b LA3A@>8dj3,0ned.C9%JHBg&lDPd9#)n\@9&p)jY]=s!9 :qp)mJ3#7,;-Nm`e9lY@:m]"The#>be)i8Ahq]g 7#C_o&cdPH13j;Sp$)0sqL`Z.WA8[L%sSPF@E-(\S\9Y(fRCOm4p#A+/.-O(a11A$tQm_(R)NjCW(2f_' o<TL."!<4`.@SM!<'b%HSI$t&j)#!<Wh ,9Oj91s8X\Cb6M]3nnBlIEnkDQ8ZRbQOc"P<q8n--ZMNV#jA`Z=gKe&t/66IcPh>fHL0$??.r'tB.`X]ZTY-740RoY&iN5STW5I Y>I!rPHtYX"Y/ ]m]QInX!&K`NQRU)A>OG5&En."WC4<;4;\=BB.gia@?>Y0'ASF+mY*2#Lb[9B#JZ%RhJ<>fc!Ae*daYAO6gYGjGl-!/h69M)#jlf86;rh<sq1e06H9`D4a:\QGK68r%_AJApp^r6rn-q$h+8o;^HR@AA:_*O#O2q)6>Hb)i)DV\@*_9T:__^KQ^l @<85s9 M6]?eA!#Cps.,Y$ e<B?lq`ob11&"+0p!0%L'*]25G*f$f_n45Rk_7\3_%Qk.TAGETBtgV3eb-_@XHi*ed>-f$32>G2bhqZA!B1LIA6@arX(5L&:e!eg0X=_bWcP-%",09!bEk^C&Y!irAW36XKqV6/MbI)Ak![%,TPZ/AKX0]*\WPq";OP*pa)Ki!,)$\1N-X$@M$b!8<;O`$8OZh_`N0mh_cs1/7&k3=["]tI-OGV.oYk Y2+.riBdRQ7k\d8GFpG/PVm.]tlq>RU!J_h'fVdeSAbW[^.iXN!f<qMX:0;PEoMR^?NslZ`NHj W/&G&!Z6a4LQp]2]=t"X]6<NEreD:Z<PrBEW)?^`KRf9Zt)9*<i=e3L8q"3d5L0'\j_PKdUYRLp069hp*/<t,R*OgK#ml^-8&AN]kS=IDMlD0ZI3iiIAj-;MOY>#;cO[m]U9NstB?Y`+Ab(IDE;'P.!Z\N@8!HZ>d>(@m"p(lS4/XIEKNZ5h:\YL>SWGK#]2OP.q;][.s$84/9FJeN')"(&q42g3SKpVUbifkn,mpIT- @XaW8j?_3AJT:Voh==X>+ ?1)iFM(aWV4]1_hI,\Slc#pWkThsicBRV[AhADB9KKPUJ`KL$eSSPC/['K8(hb?AE3^sJ7;;oEH6A8j$#1`AQXq]ps9,Ap08AYc/MO]IfN[.]7tD;U%6lh8;XH`s+'p4diRJ%oF_4b)cOH8 /J=sS"0kO<gBSc8Lf:tS5Gk2`_Ed[*XG@A#sH@fAg?QcggR_AJ&qZQ8mE<6R _A:&n0)9"WXr]aZ9hb1;JT_;OU0h[Kqdl>l)4^H.]mP3:cCoJ8V1hl+)+2d7W Dt$0'FNfB&5PlW9$M]DJE_D:(;N(?$o&d,qGsnX ;1dOdm0c.Rl^Ct/GiDTs&^SYV.PW$"J@8 b,>I-<Gm&@`:[p6h-V:)e7A-96;h8:[364n4pA5C8I3WTj%5k)'[,&4>:#.aEXL8niGh;KrT F$=M/DjA'3s5/9@r1hqn@+HYf""RWe9Afnlh*\tg\T$X6dE9C#q[\0\:dFf4!-]NS4`VIJhs6-=6e2lT5cCT"24i5G$]2n^Bb$3$,R6:ZKjn@n.A;.MEscbH4 DdA?j8O`!mM#7p (Mb(4\qBrt!VG>>(BIRK#@Z:0AcaHk=6AL-/"R+&S!c-BagoA8,om0\!GWbeO<.R":,J>2aU0%PFdYd004$69J5;\tLU!5Ym$k)$!cm%OR%btd4g`bla;Q&(f`X3:4DeNTAmo=m*:p1]Al3O5H8,'4G6c-h3;7n>Fq/)Q'@lk!K[k0:eKGq8'^Hbjj*^%?XnWb)/soo."AmJq]dI[KZDV&75oA*F:"*VWY1d`DAUtYXFESlLQ:A9c_qNT^NYs.-:rZkgJ".PD:)-#CMDPjY3^/mi\s+r67s[c@V=;W6e*^PJO9`@2fPXRojZ9Z%1+:OLf?fGi)YF]!H %Bcbh!X*+F!)/)#Eg+Z;c*f^&2;tm2;slJSP2a+& \W;9)_LH`"+S$tAU MQ+dCr^ $1(AY!.b-2ce%n.dInA;#Vipk<ZTp!@%11QGD'M!';#,H>o"dmU?'\qoV[ngS)K[\IhNC`)f:On)g3&qdb!?cQ&r,.UoSd%9KA8O!L([*H.!:j;cE7V65ae>>K)=('.65D3G;+]qYa4Nd;5l+PW ACE1@pAZ!9fj`ksP&cNdARrG dHjaQ5oVOYpEt>,V<p)n9MF3r<fAH*Y)q/2!P'XI_0.m'+PPISi+df=_YP42`P]8hh9VI5*`8`_F(k%t`FWUsFa-g!M3EB[9$=@ptPVQE;?!0CC8 i+Scs]<Ys,t*BbZ2 J89^"H;`O.8XETtXsd4L#I-o-Q#%GN0Fr')D'bg,l^]mW@^%MqYtbp0Ae!K=0TBeXY2GpWZ@n#.qaJHhR2IelC(MZ`76Y%p0$QYS"H"^?O:<Y3(M9c2_iApo9aeWBUcdk75sd+`R/_$N#%,7.T, g8RAMjc`4r0OY#;\J-+'Y2s8taO >3SV /T)`t (A(e3UG*B:$*U%1qF'.Y&@4m;$i R!&GXLANqSP^N1$/D5SG9AP@nCAr=gHZ8G\FWrDbm\'IM:n4b!oXSa#UmqGQ(=UD*99GH#2FAcmitH0)]lAfKB;T<fbN'_q=TPt.AbP]s=6gRTsAZ#aJ&+`[3'.,nkmM(M)>S5Q$tR],lh]mC$AP;D@ULc0jXAAT>pBH_EDkoO7H2_oUJ!P@01V94VqMXTS"fUAS.Vq8W7*8jMn9>mJBQE0?C@1KW>E7_AGr\BQ+q/kpCe2B@)'1.3pE0P9NbKC$`5X^'*+[69n.gQDdk!6N`c(r5CV8O[#$Yh Ur$&Z?,6iif)l0lTtGi%Iq;+L3_U>Y#*78dKr,BH6An2gR5bcap^l)Y3!c&>n<VT:7o<)r>.ee4 aE5AcSdA>MPOSQK\#=r&1"0_S^@0*e--@bKC&1Nc"P;&2Z:GGifAL6]:t%t"Y$9O#GW]?-?>OCNKs A@-ekH0m`@*!+J>,/WJ9]kt5tQC6j+V'VG<.77h*g&)+G9nKA#5TAW\ti)&M3$k/7W?A%\=P*&&L]kY&rKk!kjTUl,N6R7-cPUHak5odkeHZH9A3V/]e/;fYF-<pP^Vka]?L%Wt!> 'JSsn/16VA/c<cMH<R^q/)0e2;0#JS*Xe+:^ZA+@)L0T3EJ 1lbB1h=[9 QmbKjA&XLtea]?:Kq.jhNK)7a,bhS4;J%1oUk,]tlO*Q.p?H.tDIt()%AIRd@hS?]l4F[1!8eqI]gkcXGY9AIHK`GRgr/9G,oWDWTf\o=J]eNYPGqdFoS^/F`V;UhkT9^Z3a-6;;9XcCV8mb5-90k Xmq58-!MoS=8,7rZ;cs*fZAMb!<CkeAbep3lEp[jA#UOt_+rso4GBAt&E8rg[G8+pt6V4DJ] RFDWkE]hic+BC`XB(#,e[PrXb8N#OTM+.a$*(GA<g 2:'FJo+n!I9ng@d9oi N9R )XYP`32,r+K7ma4 X3`\4?)8dR6fAA>,(-q T)"`=2JkBj^:aT8sTp_+2o%N:b%QTZ\gnq"t4D_1B<2AXOUM;O4*Ak@I\ENSP'eanE/Y^fL4TOAcV4an>(*-1fPMHG=)$j4j8tKb`59DFSA+QR?.;n<(j:3sr33Q-o]b5;j^l<-Ua&+5%1?7smY;jbUM/7"Zf70BdK@GnRNi%\2A+%S1J/`?(NH8JFjLeJ Z9$Mq986!Pn6H8E=Eg=k)e]>^Ad=?#rpK+J^5QQsb)oT1ch=rtJrj.c+XK;Mk_e_dc ^YG[aWPCZd!n,D+1F=_O\K:LU3"G'rFViOQO`B+PP`%XRnoQg9V:YCrJjl'rh5"HeFCLg:B.Ic7r:&F($UKC>8#C"lGT*p!A\3'_A*'.InVC1n8Z@F<O&B45YQ%bA*n<&r7.WlfF@>O;Iq7_7tWk:q")I#=4mK(56h45X,q,9s.lG#mPRAAfs2l/8MBX_na39RX1B$7LKc'&?bV/'g' k_D5I67WP!W/a'l%;ZWeAH"f7AQ;OA"^*oPXQ%;8;iU46BOD>lJO;8k,[Z1W`N'Bk^0Q_7P<#K%b*cpHlEFaJMNaHL>>J(p@9OVAOb8]Djdf+69iccX jG1Q9kqd*.,"lmC3"mYNY35[,2A=oIg#`S8OJ#be %49a81hN,bj1J-ZB9MYg,p*,1gKDe=>lr'+(fb:U#_eKBV(:H8\eY-Zs4bW5CLo:PZ]&V ]tV5`';2A@r:h;k(62p]F.ga5.r%EH)=f=AlBO-d;9*;n-=Ztn1@/-,7Nm%3t"^-?+sTCNYq)pZ[R#%BRe&5EM98USIRnH]R,Ij[aJ5#GcDL1P2'U%1U4B-0pLMZ:],^f*a)tYI6->6F]]rp*Fi! h2_=EaBn5D)(F?1amaLA4)UZ)\;;4B8F8PAa#XA\=$>RK>aPcH's.cHKk<BWbJU:7&jj98ZP5/@p%_NQLhE>9o9Yc*7CO;(m<DreX]hQ>1f5^ZpkRf`5#?(],]V@j"JEi_U&+ec^F9L+o6S`$P;g':4%8Z<MZ]C-&Y)X3#^):;bkY-`MWD?WY4ITg#;T&5.PXB-F]a3[st">IGG_$22bNQ589\KG%;CdqrRWd"f"GcNj&-$QNs2'2=j6AojYZakT>_KbC4HIT4.^o=ES8*5JZ1<(!\Fs8!r;!:!@U[/oA*I:A<UkZKmV'rAjCFA7,$O?h)W XtghnUp)YO&g_sO%b&`L`TqZTi&s\"<%DbkaLEV2US2PV$id")V]d9E6-=as:T:%$."r)<#XcD2hH^S77"(gi,MW;ZDi7k@@e6YIQ\dZ"1GBHB-N_BK%A/WHnX#kan&g=<!g"?[,\!\EGsZ9@<4-IK-[Q(3N]?-+Zi(F'HZ5L\,$IE.8$;Gf4KeiqHA]nUR4)r\1dqj()?S=l&]`gfXAF'K:(&f `H<!-DqdR#aKYFFKLcbp0>eFUE.UE$^[dbN6./B(o+&Khj";/-h7U]"6pb4W:3Gd^'+82&iV6L$oar/'MR?Wo,W"@YY&)#&_<%eETG(I??e'7cRH$>%H&b/BCF"pt+97)2YnSV3Mc#`m#smn^Y9jpKoO=e9j+fnJ+/V]Fq?:kpU(tq8hX\Zl2#ppK'X.Xa2UdC95c)8D?q!AQmHL.qh+?a.PN;ZHUmo&jm]dEnA] fin@9St "5i+L-4s,$sW Kt^;[K.q2QQO`?!m\?:*]-<cpg)U6pDr]\21@-BmSIt:YjN0l3kdDB3c]"]/PIRn<'5)Wp@b$ =o"JPcV@\Y:,#[m,R;G$qdBQ&^2>j;5\Te*TYd[R*#XE?R%JJRX*gELE/ZOMoP'"i-U[8We5H5qOj30C-lI1\#MAo36hPt.caONtgNM,:8aFnFomY<fHcg[Hl8P AV!IbYROa,4^dDX__$F5)S)b2e+73K [4#q_+mrX?'YC]N2RB0U(S&QQ hOgA,AZ0`qb3V'n35LNK?FZT]%o7_G4B)+dH!WFj;?`(OA0p<tr_D)-h+-XQ:Q9,UH[4R3M Xc7#T:Fe&#h<:H23V*WWo046t0IM*G9$@%ALWR2C?ADqS3e>4(g]IO/H0$Sc3nH@nd0n)lG;+$%`nilmb*S[gZE0_`<Ab7&5h[g$Hs6l<p&6g3;54A#Z=W $^m? "RN4LN+&Gr3.`s:f98/6gD,<HA>Rm/T>RR%">8C$4 be`Y$@B<K$s&?R_MqP#,lh7?+Nh*F!&sN)b"%3P0q./&hbZ K_tl(BPd%#@DbcW&:E+eJH0,#@NU!Rqn\f9U^EZCM#XXWgnh4eIcm"Ji#dlEjAGiUt7`2^X.([Gf3s\jEJ=ZE%"@;Ibi,&Ill,[nhG0:1Wqc6"+G*E!Vjqhq!,n3RTG*4h4pl?RW(9U\mYdNrK0NBAdOFf>j$^Sdf4OY_N+C;K8]fi!4g3cF<58F-dat-XT:DkVSopo4.^ZhsjV/eX7AEPS2FVgB$'&Xh=VSM$Ik07PPW6ZO':)3Uf7)dOK8jh_f3?H(Jr=J.LgWnT1_eA=M1e,6f!4%<&&A2&DON;?=N_kWlt\Kag$9 26W#;7 crF(` K+M`V"PfX,K%Ul_d@0i!KWfX*OGp4i=EUbSAqBrLALs%[A.^,l0Al?QEaj(amk)]FBXCiYK--?0U(pfC?q!+_=@mSLkXrK'J*gge)^B-a6n'9Hs)75QM5+cQ_[B^[je,\&h0,L2:n3+V:eA6RKlQnAh^: #7oU(C74=K*?8a@iMN 6)?Y2imWkj)jL3t=2lo%-A%Gmm6AGXq_4!Ebb6`hLDF-N:dPU-j=o@5]'ibipCDlZg8,*CGk`A71c00>eW@`lpcN++U?e,n3\;Y#a($_>;^HrjD$XkV&[F,SB1n7gSqmnJZ[Id1g^sl*\E]lIB<oj:'TWj$k:erJc7cB#:UY/,soH*e[nmF5hk/+"E]31?=^CldeS;qF-frFMr]d0s8E[&`j^Zhngt?@jiqb%>^ROG<^fcY4L[M^]n*O[R3GnNg9P/XAAM=16F,A^V<TeQH,>M3/HLLO3#gZ!31(_R8kt:X2EhY\#6)+[`Q$B#C"A7-qpb/JiZ$eMFkn^MD ,TL4B?tXT&-c,/po271,` L:QjqT/q!K'EqA 6n#[#UY9n`TOWqC)=[A!8`QY#;#:fLP\"n+9hd&@S8<L/Wg?HaBIt%gi=K#]t*8\Qae71@(a;j(FHc(.siW;\+Z6Sr!A*.bSSjG[D:[SV]`QQ>&98>gA1=@,sIE$B1.F\m[c2-092XJD<`_R109#40(RH4j$j'(^%l%LaG[tiNdNZd*L1\p&tAXEZ$g?Z02SLek*3eor_IN&2ML+)kQAg3r8Y'\^UIW-h=C1`3]Rm:6]k..&0H*fa8l.nU@9a"kZS0BW6]KU9Y(_gF#p kT*6NY\(LoI+>=7e":1nOl4V"$!IZZY,B8hj6fhZ7>HA^rt'%q(_IeAAN#$#"8MFmA2qMckc  cP)2Nn9;YF3LqeBr;(\kgkAfI0eR*@.h`&A+`ESKeNB"7q;S,6E/B'U'\'1FYW[5,sBM+KgV1A\l(q.oU7(!F0!T<MI#A;:dt2WI6mcC\`WgY4fI4)O-*OT-bBsfU9k:)75H"QIg8B2!CH8),!@-B?;k;9e@L%n))6Sg?45t^H6D97\-0T%b+pEoA3(Hn *@9\5L59I.h_Tjr^P=!R>:g&.X(<$bD-DS]3<q7*PkT4BfJ!km`,/j,&=TXKS>Cr[2U?^/0_g%5=6=#cQt:]hj1O7-*[drWco:"b>R!sa"'8k_dU;QMV?:lSAcFDAaK\bO':MoAp_lAh`-" EqBL/@I)1Q -:'/=tR0A#;9N?(II?^7"Wr8-.@_*/KdAbk=Kb?6/5k /l5J:::)1cNJBbV/bC%Gf<"1r>kprV$Fat17n#07s,X$5"q5'M'%q%f6Y%r'\tr>+\UpOrS;&:N*0&?rVlQp*q:9LhNVteW"%&_0nP]CVWeWYb[mIOkkDfKdF9END]C>(/EUcC3'KtX3)- l^9"AmN>%a7htW0sKW>ko+-1p0A2NPU8ZpPV[sI'QOYe4+[F%aIY!jA `E?h[:=BrTgJ4p^1d7sAitnEHsfm)?\MJ1WA/Zim*4V-B3o'kMrct@h.>*OB-/7YG=)EW.tj!CpSYMa>CdEqFI@`1G#apQ/J4LV_VFO/PS]ZRV;s84(hSM.n8(`6LX.,jiGkF5,*UkI$H> /@ArY_7EOm)/2;6=EjTI&*#\e'#*2*>k.3T'0C*o0^#OHh[&"W6Eo2A]5GB6S,?"m$ER:Pi?aY4pH?Z; A,m!K+sF/-oB >-Xh?WQ'TI)L'mBJWWF>%mY!F&X8ZZ0)q2UfsSqZ[X:d0[4EWb!S7I(,FN3F)LdFX^3:`EhCO=U9>5.6\R;PF;)`^3M4EI/A b]Re\,*TD!C[T"iYIj^+l.tUG<0&ID.JdLFEF,lrZogh-JT-;a?2`HS7"eQ+Ng&icHUr[3kn'?nNUVD /b@7[cRe(U6BA?<ltXNL(\1rAT_cr.IH8&2GZQ=KT!*moSn^:b]=SUlC &s*mXBh-Bq0%O3RX,b:8(nBC`tYafYW]A]tJf^b`;XqJ+m^7q;nPAC@3p2T9cEOd_[J70^#Ilo-0F9s,1"K`=#?,^s!OqC*X],J`NgbSo["=#3SR/r1b4RaG4/i;]YRj7CL2nmSRk5qB6jqB#K6dAi1>jmq>ToSn @6G03!ngRd&*ZKo'Ue,Ll)_2'- h1 98UTlo@LX@i7hgRUb\trHlfc\epd$Dd'=6=tm#:U]S;d(`ABONL L6q,6lVID;;TVbZb3oT?#!cjhA#S9'J =Iie<<Ubr^#:;pOhpn.P%"P0<&C>3KV%eXg9ST cf%hT!aZIG74l-^bP>18WA:NRE,1<W;ioB;n-g*(PJteLc38\2U-"74d.Nt;:ofSZ=rTdIK*3^n&d?['Xh+L5n?C.j]T6l+>VQ>8n_d`II+&4Ume@SeS  Q`+>dmTNhhU+8=+gc/Unj=\LBal9)>-cT7]Nh_,!'&2Oa;O_!p:NEnWnKsUke-I@`1=nB)N>[)qs_)>E2r3B@c%N0R7PVUEf['eeAnFZtesX'+o>$5Y<"i?6&_Fj*<nm*UZ_nXNnnOek6 W[0ej.je1[^M?MKO,G%A0h#Wc!jZQKcG]jfmj1 gE\Ti:!7"`A#jO4Q,4!TI$2A(S;),-k Ia!GO8inSYdhSrZPLGY5m(S4:KAn(NDGpsoLs^38'`,>iY\Rr]5)>7/E\e?mp^dUAn]C3?#T'`oEe&3R5g7t[U21bj#^2t?>HAVAb)D]gf2B,<VBQV:PMU,nkL>esZ"shAWS=WN)5P.p+TZGN3\KAkAmHN2DbS[<A@RE3@aHjXFA([<8LrV%(pD+U1@=%%n2/'@[\%?E3@emR'38S9#&e!R1#T?B)b:AEU<flsK&_XEV+QTV/)/:_2YO,6nEkF6'T9?A.'?r&9VUnMC!rRjX%W9/A&53XK a2;9tcnD"Fm4k<ra0Ycl:*?IMgkgm_>V@R1fS`Ti50@R0>UdFAK1)Zi*-J0D7j"/FE0RKgkB;0iln2Vh\<@,l5r]`W?D2+"Bt/6X 0L>3\066f+6tYoOA`?=e&r+4_C(F?pZZ_h]2V0&2bBhp(=3Q,]EGTePc&Co;lFKHts'mB>=OgZJ5rFRoEQ6$W?]j$BT@RHgO*82+a[@NRqTPYs:Ks+^NG+2"2jF(5!\ kq?M9_GhBC&']rj'Qj)AhgNs#OnOQBXPO!o0&=nZ!i%DX?:cOY,2Y8#2IALK1>:R^N+o6hfqpU f[O%m6lQ%_I0=>bgAG'%\7(4Tm+LtH]Q(f[KYjRnf`W0-B'*LL- s90UE*\Ks5< =BWFKc485lcUBk(R%gULHnT^KAPiWSR6 ?35O?d<ff?d:X)7qR0&20Y"+F# 2jA>mV- ]mH45?&LV=EsoB]%)!*$'edIP"HG+V/A::SkJdA1k+@K%D:IB_ENml)0&r$<b[)qh6Ke(orDDnsEPjrVWQot<!(j%'>NS`[IdK@Tg>Jq5]_0*/Q-KIb IWTFA!SDl%\-:M7ni6Aj9j[^!L?`ZS^T47j`e`*lc!hK=rb;UG! #CL$5c(3iTti:(pCpR34`];*shFF]-d>MAn59AF1a_E2<NF57<Xt4jQKmk 'ks'DL^;mk\(#\a6&B2pYbaN-R(oKP$>>SbWX_0to6Q'":44aKk4,_OWN'WE+p9GES&eVmA!ZAWe;*qsL/ l"?l1kg2d9<5jgb5\#OmVf3WH4:$$ad*b>=G)U/n7dEeC([U<@`qL2iOVk(Dib2-K:K?Y*r+^A^,72qI)JQ>.VE SfW`"Qrg1`cJ!oAKC>O @CpG-A0t@M*]8=":inR=\NnGXpC1+<J7f1QKdi"G &GAc37cmGW'*sk!8:G:AZb=k8LcF0l&+[H=]J%m,:gflb*.i9I?=;h,UcLclokkEijJRo"]LiA "]#^bs*Qr-PeR@k9`_6Z++1R6"&99>]3lQO]i?5P-WsB0t^VO<idr5N0l8S=<pUV9]A&#(PAR+fAAo'$Sr6A5BgK#2-amroKkQAjs7'beCcn/;)!*lkA-\iAb$=*_DA<OdZ_&i1rN;6/]C"@14U>rZ8kQAh<njeqG0W`F-t8J7e 0f[isgmTg5$:#KpJ[q`""%O28,f>M+-/3'N7[h^&Rg#A%K\^9XV4Rl gZWEKgPEG;$^iRChYtWGPlp<8#\6OVm7h`lDL-V11E[4QN:,kH"\o(<)7`=*@tKW]66kb^#jiLt*/%]!)A1(Vt]%e;K0FREkVrC,XQJA'Foj:?I&Zb>^Z+4D4"A9)%`=J nAEL+q\'\F$kAP627_qJekh$gb:_FDj/*fM#1<(;qNmOX/:T&7B?EMGQ@QAs.O*o2ld' jcoHpC:/'!;`CX*#, 0M[`0HB[A5#]4&jDdoo' tf6e",o(9HXr,bVrfLCL0Aa.bjVFXVF5P>b%R(lpHU*'3XDQQWq-8MECG"t"'dj!OM[_N,FfE40OCHd6Z!'M&6f!PZ0t+@\2#)&%Pk45Vf#O<Zbbpid[CjWaL&nd&DZFr#6he(H@s]ah6W\O;[S2<>#be?9I.6D<CG0:7!l'4-HNnB/`+>kcS<X6L"SfT*23Tm`'LY4/)o%J3X&0%2R1&)qc/0O3LH':V?g$d!ho*i@s80,\#"aM;BrKe-ggAW7Ib6j^GsG\@:U8$^djWn4)8VB1->%rV/\^Te((c*l7+cDmM<W>aFCFhGD$Lh\ID5;V0a7iRq<ss]O[b<]O1FBh7:*jb&?@?)&RGF]%/C2;&J+%f=Q>dV)<],d-e>q<E[ (Zg7.D!\4EJ4[U(b@(AhmE`_OS9G&&pdj" q3PHR$me3_LRA`G[9poS)*7?L"2_qe3HXV^[%rTArKEAa:S-aOS](?hsJW_/7R\[+%;pe*kZC<@(q`<8!`&7#4.OoJfbpo3ig@50+m*eR53JRhqrU=H3GH@^KM2%<`pA;<7dUD]9FE$tYmlj:4&)lWpjoXje\L;nHsWBi%7Z8@%W2M>]WatN3e&Ya$P?d1_j+a6i$FGQe [Ho%f;j#Qt=QGoBobQN?lP1[f>fL:)H^SC9A[ ;\(Q=WAm6cp29%SZhY@(8TsDkq=l3_I,h(g?%q73K`h6-55N<Bb"<b\qiCo;QrFJc6nT`ib7p%bK]Z8Uo(27M&*.E"M&]] lBHe%8YL9fSs[i&o1*qNq$\A[-3b;`9KbFn% MU:@"4#9NFH/B`<"#)MUg^'k_Qf4rEI<!.UE0!%eTi"%_=E*?qJZhS7.2#l/]i(bnr=1mN@N7X,5(WfVX"5(.Ik%gY]ibjqG>igo3:!<3c4d]&(M/RC4(eIiBKW,oI1d4!(<;B >+HZ0)e.bs' II6_7LN#)q0a(AMn+>q59C$8oU0La]iI)[H9,gNXL4&:BUAfcT@[h'dlY4tBR90i9=:_bb?\QZ673eo0Ea?JZDAFnHn/UH6]C0 /t-;)e78-B$@6G%OBSL1a.\&FQb-+OUZWrW&1ecmcSTKW#ZdeT1+ApR'5DMSQ, 9Am& )+ e<2W.Wa?CO"X_l"lQ/Q<*[.hDltZ^6JjC[PiL2814O$?j/QC&AnOGmtW_ b]KA( 9LO*7FOICC/7dr)pPH!B?r[;`^d[\V2,^08jK/C[M3k,V78XZ@LoJf\HmZAko6>rTepb]iPgEQ!;4.c$ClmhP9 1T=6&0GBA*(Un49P<=BR:p2#p&bO!H74&n`98`_,VkA6]t dGYqeN"grDXBFk;-"dNOARN[5-%).(_NSa/RE::QKJnZG%f"PP=6#l'D'I48qT\;))GTV2K1E51o"_6-RH;:$cTB5"48AR<+U*>A7N?5J+iEFl=h2p+f6]h.fH!E0CtSO7t;SK_/h/-^ndjRX4$rfi7Onn#B$CE="L=nLG[]3HB=/ph65]@7dB7P#"MTBSV[P-60h'#NLG=klt'MR8q=d)fN])[O_`Ia-7BMX%eFAkcF6JT8MYV!)/cL3[cj3VnH$ &O"iJ_g2HosF.@ To@V7OK2"LsYYcAs5>M+d:Z1XW*e%Gm*K>tcI$W6Q<m7EInq/U],5G4#:r7W_snqr9AieIk[DsKbjR*EesIK>:;KCW8U@<iGC:efI1WKpq5*f0gc`oGC-Wmtq\Al+mGjk*8c((J7.$P@<I'/PWQ^3 [M<U_1e;3N#q,e*I>LOlgU_)VE bAQRh6)apl,gr3^#@NbAij\=Sg_"teo$a WNJ s\q8+r@pKXeJ*sh/T'M=L+QaNK!gdrAe+n+FWDCZ"d73O&/!Sn/0.[9[> *,%SA'G#Dns-Q(RBA`aO7ehjH)t4Y>ad%^:]&QOX[M[-RS5W3846J>)6])AO>s&GdJcAMo[mJfU<>YkGoI%14nSCT:feac2KYL[-! Hm.Y7Q=:(&B9'$OVjb=d*e?S5Zdm'Ar!qIRLG soR`^Z:ee +eAt.Y.FKE>i*h$BGo)I4L)L;A(P!-]ofO(X1\m,kn4&;6HQO>TAD--L"8+>W$6m'Yod<GBS 4$1ens['o\'?+TM1IQpBQP/k*mtYi%&NL""F7t rD]T(-,tU=e&hqTU8r$:1KQ4m<DqNX3""9'$,J-g+2>9bg_4 (a%XKa;;A)@t<"XXDf7j(g6/+W`o$%[@-c;ZRqq,9bkhLBa&X@(>sY^DS2fB`Aq]pm'8iB!RsL`MeG$<n%bbFG;ZT_,C=fKoAn0`.Z\6>atMf'^$hk"i[r`s^LS>(WP-?,oPj_BMIs_1gA$qsn?'oA1Z4Jf0BFg8n.[sf@=gm]33!6m8_IK6',"ZM[M>)ejl/M5S`7NlJr(^!dDiF[.n U%6S]nseSC8=_2>bcCgcoW!sAbgRfL!kgj%81")9\EUQiobP%Cd`[S%t/WV[A`T+_WFrsRlPS]gK0G?)-l)i*_X"4J,[Vl8mQb= 9Y(a^=%lViQp(feU]A`:-MU`^2tA#_mKUj<U[ln(,ai!8it:%F'1nCeHsVA5gTbn-@*%Q>SE*h,pKKl^n\bg5LBF6AiUAt tY,8kJ; B:*CQk]!fn4<&*&JQh^]rJ`k'j?PUQbR*dHa<FYHk *jLESb/Y3>YWN`IqI5d'*L%2HmA?=HK>g73Ih#/Xke3&c^@O\rHG&A1&F!VPW^2'H.[9WD[;=#!Wk267l\ggd@B3(CnV"@!^C*Cm!@8dg6pIAiaVY`omHsisq:(]e_iW)(,.3 '_Y;bm&qQXO[_c2L*>=U)U@@V6QWjlsCA_(^TWdoAjC-6.^kp/8PVmW2pMq]*<[rB(-bHH34$OB\;86lq!,hgU*m&"",6e6`dNO<;S',0jLdrW/-I\P1IJV##$>:TEl=B"$WHA0]k*cVFE+#j,%ZID]KSV=&2S=<XD\h!tWF-.maP>L(qS-;P%%"9'*IqA5:E(-H-^IJo4-*9<L[D_@F$SRC/WcRbs#2`+"a/.2'(ld0]^PMBfHHkYf42TWB'd`9LA5\>o]ogIIqd^G[U"P(ngM;AYL)a\+on0"<DIEF&RKY b4#dbB\N;Ss_eI0cNWF;S6$_N9ZM8`?4IN)9-[M A?H=9RqL"]"V30(Fn(d#- ATpboT=s  B\q&s6GkUoA 8C7.Q.`dP)!oV%I$cesctqRsMFS42&rj]@MZlMsC&$&6P]>$+A,iYLYIb]Ok8_fBRloV?h^>i?A;VM,5F5!O;mI)Dp(7"H4E+C8$M,K=ZHM3iaT?t;s*\4tZ*f-!dB\9UqF>siV<VlSi619AtA_cRe0I_E)Xa5 3aP7#M+6\jp5\D_I?$-Eh*5gIaAKH[X#_-rA%PiIQC-XBWRC:Ct^<fA$RdGAD#VN(&6l)"otBPmOtE1e=dY!,K`.FS7%oC.!:4V9ggb,W0X]]%dtHA?:i[0LKsX)?_lmCg$Z9b2V8ljqB%g/A"X6BBAFDA16s(VLC2f[:mAAZQ4kcBX%1^h>D8lFn_eNf,5In:nD#h.;fF#M\P=*J,DKKM\,pq1^`=90Q!e=,@LU-4PFS(IJm/J$0mrDUEDlDZ/<>SUO"MSWAb 3ER:/YH*ab4%E-KC g>8dCgZT2$7/5Q?8<p*T'SHb"$frE4\^<KG*A*+pSj"",Qt<M,Xdb]Y8n4!@T<:Do[P/8dIQeA@+"sD-$63g);7?\p`ihr:<\/ nf_A`RaC!]B]-!h7i1>)&MqjOj34>%m-^a8GG<j)p+YmhIaGFg[5=.Cn+To:r:$Ido$jIrj;9CIBUB<#s8oO<tM:ek@(Y@$,D1(g,^LIWC;F5]r=6Hhe"L&l]ohA9Kp)QLtaXKB-X0b6:4:L[bPb#;B.O($=%0ci#agASXh4p 0U6l.L:t<_AA72q%Y"1e6J.WqFIgq5!MDQ$C\0U`HX9hg L^6D,BGRt7 .%fX d!N:ZQ0j,Fc9 9!HBmEY`#9%bU5>*P_fF?dA5rhNmWU`@XTe,O;S)EF%,0Aj@T#8(1A%1:!?bI?U_mGggnQe\\1 1cTr:Wbbg\b 4RGo#7Tm]\@0EaI]:G>4:2CR+IQ<r=/Y- \^QC<A;@k3Bt=A A@QD,^$B$7rt9gKP4$QlsnRSU(%aNGmBsG`R>dHmOsFBgo2;1g6@jt1pC'GAaa>/HM16?i(+/9=h'-[]OL4Q0&eTGc8GP:A'>O:1-$#.AdI0Bh9aALq^#XbS:^>me<*kQ*H&g\+oAO*#U;L=M;?#!"b[^K*?iL+1seV,e4]M?p3A(=L3ee/?D#p#)2ffq\lXn;"b N]1#GMBaGDTEk:[<n-_qNHo6M4EH`3*\\h"_a_3NZBf4U?SW<;YeTUM?;ho_2;(,]`5F^f7dF>r(4ZF$j50M\K5W6NIMrpMI;E5X@I:nZH/sA8 3)#,l,1J`/8f/gJKP[h%Z5\"ir_WiH; Gi.-dF4UA+#(<t`cg<W$J5s=kj8&$lA4pS\G]FF@'NfC&YU$99[\lG.F)1&s<!XIrO&k$r]KA[*A=WGf V2r#pDWYD]!C=DUW/dG<J6a/a=FHG89&FeVM;*_\i].@;bd\Z03MrH(9SU9/QZ*Jtm)Q^6bbL)6 H4C<tOF+\s"gYp*[n-OAkRA%cVYK-;"9o\)I>`EgB$!\CiV2nfHi8bde#CNHNg20q>KZh[O)2T2+'cUU'#L>iBnDJG]`*"i>:Ua<\bJcA,b&*i3Ct02M))Q$$3LAH90I7TA-$1SWpR3JmHQ<)ki([726n)#$LJV,] k[ZnXs")+P1EUfF--*kAWRgp(e%h^Asmq_E<I.W.q'B17B\ND/M"HDt-[;51:[%/"gh)I/^b#Otc*V5tSE+b AcfWW9`Q=B8V3J.Gn3(_3E!3@^p/`V^3GX`lW\2>WK[CS,AN5U 'bgNLlUYn]A/FkZ]F9KU6OtVFV$>M*1!/q2pKO]8#:Q4'9BA@6#N/UWi@^,Bsq!R32;%Za_A-;;q+5&R4?8endVAd#"[O-?b$`E**Fk "Pl@d?3>T!taRl5"Q=GW"IE2?;81%s_b-n7jH!"VH[-Y8`^?[#8kBfN)oKgJ8?k8lA#0V]i'[dc'tcNEbaV9XT_85*(<5S_W!m^l;h`Z$`U;\rVKW:V8RA-ctGH7O9roE6;F0D*$C-(n&Do^tXcL3=$%@K3&An&/?/iFaHn6&7'X0!G0o5ng*#fHsl*_BQT`N$fgYGUC.Le]JG@NV!fAS0"WEGApT!R/^)#D]m`H'O*kPd?&kkAPrR\(3?X2lX1D'"*Q+,A!:</BMNMZRMT=QZMAgA,(WW:kr,tpU2o5%YXolD6!SO7?#9`;:PjdXfDA_ZWVB2312&rXY)k/GEQ)I]--qt A811(&AQSTQK[_ K_%s8AL^n7td8HYL'!hq^Uena/5L6M"FQUrU17qncbE0F2%jTj,e?*;RUE)R)S;,r4HBpG -OfI?2fBE(U&$_P[U^o[AQSp+BKN8P$2Q`B5YA\rda ^8tTNUr(h)4fYhg'Dm-U6%m[7^Xlta#gD#J%.mJhc#`qaG2!^r_0`cUJ>&N_W,l!H_'PZIDVD:X%1j40E[>c#3l,j,.JdXlY&NsLrL!<ZqXLS^TeAb\QLkQ-J7Z$&4lr]sd(kVX7J1#5:X0cJ9="( lF4%1J@eg2IU\dcY7QOE5$B41?BR-onR6[U'P(Rkn;k%L)"'B^YF+Kp*p`%T1Gmb?NTl*e'-sa3c5qb&6=pM#X ]* ^3WM7JP4KgG6Sc`*/TCn5[":$96sITMJC`US>Xff8R;6#%K2R(p%O$rB")9tr3-FJd7EYgTS A(\!dgX4Vq_'_<0FJ%8V_0U>)jDSpRJU0K79LT2(C2*?NnnAIF9a\&AI['B$EkH,Tt8<rKj?Nk[:Um6XeGmVQ')F/jBAR=!?)MA%@rbNhA$T)j(L(A##"8=Ap-J$k%korCPtLHoak4'Yosa%Z2Ss_TK&eiQlp;G/LAa*SFGY2#VJQ%'LM G9p-b@!I^A/dDob-/".)9LAarqp)<s DB3%dA8jD-VN0PT"]Ab6];DA]AIt/m0ec_3R"\CoNl>:JRd7bJ1BW6 imLcO27=Y)o%j4C/6;%[gAZ$k#`cWCil0[:sbU)Z9`f46@>X/\>MO)3kLnmtL^/4Q=^9a@N/n^D4sZi)R\]0\4Q9YE4VG,@d:V<V6NUq3^-ss4'(]n@;a8.k__Z7QP9\N#k:22"l+#Fs=9G8]!r:JGZ\pOZ_MFA7O=#_EZ7aNLn_Y/(;"E5j0!*F](5 Zc5edh3[Y7<=>?\ jrTm)Ra).W^YAq]-=@8(kKhc7O_^CUdZ$3ZlC-ZAP0"s=^\Q7':=+X^r%*," OZQ M, l%oH2X7Z-1;/p,f%i!'Qg90ll9cE.]6)=J-71ClLUS*D?Phg.t,`^g6c`q#O/NtWP1dHAWYFIJL/;ZbrMd6Nl=UDrs:\9D?#YHFK\ BUhIJD#A`faf6"1X3g:bkS?4a 5dY`"A6Z]+jeU1QMhcQ6]@,e"3)oU<<sV1`r/;M]$)/HUT3fp<N52-Q.l_1Dat5o8m5N8TVaip8'BAmA[g[V'+=jU2iop!WX+#+<!X]X" HXGoc'PIo5p](%7d:jM8\oCJQD>Ql59VhPq IO$3[=&)j] 6e!fY+9$Z;C)%p+csgdnAl;Ote]k !n9/`Wc`<PfNs)&S-cG9O0*^?N*jOt$+HB!3E@c^rN$eD8nj7A\mNG4'9'70<(_".;qVTM?:L6OB$* dl"tKpleT4\"H5h'1L(M6(A]Vt76dgr=S-;2*D+$`!kN.B@Hg;A^1-M. .OCb5tAS:S`_.Ijdt/T5Hqr>,9QV4F&Yq ?[pE_lG*nmem<mTPP'.2a2Q+6.BY0dmi-U$%.Jrt37@07jAjF/'6$!#taa;Z_f0[)2l"8L8Z(-+5*2s!PB9Z4K+dUcX@PA olt(IN]T3[r*q2O( gV,8 \5 pQAUq`ln#KObIiH$)Cm=\<BS0([.VmB3K0$1Hkq sS_\pl/t.GDGG%Mjo(P5/(d5'XOrgl2N8Y9s[.bb?oXoB@Whl^A%BT9YW1#'SoQA22s7_G$"QR7B+!$f`kK*4=B"9)*P'm"EL>BaQ-[+WAEL@:j@A$niZoQp*\fOtI0/peWG0>OL?Z`B?s@i_?J9<$23sGI OA.(ZQ6hotT-KjOi4ai.T*27jrJ!jg$3WWE87=8\kBD`%53Pibf[jBAnKP)\XD*6Md-nrH Lk'o-Bmk6SO-l=d(Wj"Amp!VC ,iOF8IgAb7_0*XW3o`/eXiVN3q2k@p=+sSiPVs7$1hR4b@MA-'Oo_9\hcJV7AA#it^L&S$GV(m1FWq38)d\CY-Bq)\ZaHDdA%"5-IJ\=S(-)^BHEJm>Nt'fdfi-`6%+o(qa2o;j$$AN\K=I$'FEap4D6p8,#L-8%-oUFbgAWiG[nD.g5p<%0FM:ef*AtRh5jJE=N2'fciPam'd#\@*R>?2Kr3Yn'RA)($i%$,/eo_p!8^#<[%1Q\7p!i5eR9dr9jkE#NfPej$kW,&Ar3N;4ab-a-7a,qt<ZH?g6f?jCUc12&^W=*3Ca6$Dm_^kWTr!mgHS:1t!5qs=#0Y[B!DGC]GV+."]o.-g:M(oJ>rcArL^+7<6@aO_ph;C`j$TeL^UhfA-BjjQ<S$"QY$j'\qK+F1lKi&?lA^3K_?JG2K7^-:9*;Z*]c_ecK?_Bs'@]fb6e_Bp<NIPY5X'2Fg]H8^!`P#e3g>D>Xk]n</0/0W7I/tDd))873i5b_lF8eeMgWec[/'ok2AM:CM^qgtP<+V^G+NWFhreGV*\l213MJGKWA# 7s1t?&VVGiC=1:gW`D jE5-=18,V+==9hJ<!'%N>EKF.?:ASU8\$A!@r+XLUlr?[a,@dfC_fN810! D!KYBtmVs5+#U"I0q_F^A2nfF0RE>t&P,`0V7._ajj^<>Q?tl^!#$O:tRlmHd!BejK]aqUCaJm0[Vjh/*iQ>D,-;S]XY$Pn2@3lh1(:AnX,,`4?'Z0 J)_` -Wr5?\r2PV_bA:h2HL'/?A1($g0?SG!"=:N+,8"hqI9VYfN4Y3?bS<;[p\3/qK:D80G$EUb]tgDU['[O)7Ht$c.7WT,dep*%&Ta_R,XT=n4G4M!/A.04d/>Y8'Z=Cm=,A'a!=bhRADYk9?sqics9TMQL_1?7:O6E:/^de,TXZ3A?enI)&@ir5U*9;HYV/nn$F"oJ#@a'%*,m6sHScVQFj/Hff/Nr ZP<'V6FaDYH4<8&i7ZTs/+FDH>2F,BP&BAM`9`$NTRCi7j*,a\S!>O?4rCV4]N1_$p>]E2eg aJ&sA^,T;n38Rj>U9,`mY@_kIsY[fbd%XmmD@p<rAa$GQ#X8&hXR@WWr7kT_j:fhUR5%S;-F7O`L*%PX;^j,gkb]f+0.TjNfbZ^M=jLf >7A6^<ZkgVr%$jTA'lpL&H@-L*Ar*^N7P*K!&W<l]jWT<bLfC6nL'*PATq^A)3Gric?9b:BW<D5DBXdb:)Y-E]i_g-<dkK'%EeB,qN+oI/e#6\\dma)#dGH7\>01L1XcG`&t+ISC\L^,7GYI>)'Z +t2.DPsGO!hae9L0Bt*U6D4g.edlmm;g(;=:h5:@d3k?@^!mnT%cjRpQPE8r8BA-70K6PS,#8mFp!^_lDl@kYfL#XtMEG]fe;d%%5:(>Q dF`cZ/\eA)^l.`3dPAi6(4VAf7jWV#6jfVD3.-7,$aT\ICYnB#et <i-HZtij'H?j\#p*A[skA5[3o)o,rG0B2&G<IpnV/fPfeleD qPU5HKckNI96ZNfK[0"bhi$_Vs;[Hl(s/U*L7"$"lKF+@ n#1"%5A]_5g^$T@Ni8M:=!doLsS>H#1SLfA?KNg6lPl`.0bdR<h.,!/AL[E6FNYF*:^t>p?Y!rl(JUm_?X)l>$/_!5]r.]f?M/B+HiL7Mf8P;A@iV:]'NX=K8]_^$, <4< qPK[gag.V7WHF@&ZKq01-"8g3E?]VK2ZLpmLgehF%SfQ"YM]W?FRJ4.V/G:jGpe\bjt^io$r<30]HJ"2n7H8Q\"o.=BsfZ\=+o)@B>S5.f]]Q'K4^bP3Tj0(q&)eP><p/6If-[O7ltLCP@!R[t'IC2BG2r;4p%%^37c#rk'BDQ:_:FXSEC_68"\A-J\2WNb$:Si?b\3jM5#OH`JS/Wj_1(#XAHOR0kgB/L.?Wtf.R_\EAT)k4o.C&Ks!C@]N!@JhaGrphTns7Vi<MP*gkR<f+"N6hj6b;0](MWcrD2)oK-0r"Bb7_hZO>6LjYG/,CVt3*DgB`+_q'9lK'-Tb+s)T27FJ[YR$Ot^!(W$beC?m[DgRN548N&LZ:/?sXs!F4]gFV*DnRMB`g8_X+a7qa^QAVgj.q0!rb/]OCp01ToFb%]qAHj,YTY2:PrfsO@?ajC$P(KShC T<Tc(k@sA-'Gj'><[^'gO?!f#B]].HBS`3X#p"':.l^7m^,J1843Mah@-qe*)t0ZG2l3FI*f]EU8CldM29$WUD<2m-&'B;kGU\$gsib7(8d2@&-r b=Q1Uo^rGFmaO5?iK+A,A7">b#Z6GpJk-"*^VNlaY> qTlfc5K:mCT4t!Jk&1Y<*CU$'d5qL">s#F4@%W&+,[e&G(s3%Bdil_&+d=m#oR/j%1CBn,`;\:Xr-` &9a#/A`5`^e%V-iR4X+N;Tl?fAKpYV%kWL2P)'<tB?j2QS-4Hol\:8@&N[^?aG>eB=4P0)#T+B,Ll@Gr'XZ!^g7iF liLoAG#MX*kLKX:'A#.EP-b$ZDpdgQhP5A61n:&B r_=$g-4AR(IsV*9CbiWH7Gs+mA+o^sQ?4(p"B @?:B!'*kpj@'^:73Y[[P.WoRKeOm%066gH'6B558DqDXp6tOQSsD"c?6;"h,msOpSBYjLq(QAJZD;=Dgg@Nbl/ d_$0:fM==X2\=m"j][d/Z7K1[3aGS$p 0.6ED74l;g"3;7*C'c*7U8NpCZTr$^9FZ7AWf.EA<X==C-+F<:$oMa=k `=-7fS!_qfOJciIZE18f_e64JQU/lCF9Q`"1^qX=6iE)Pk@s=OPT) X&<$!i7Z%]alK'D Dl#VCl,h_c"I:^IPNUWi$dGM8@sSr@&%B'XcqA_@1a6eMZ,)ABFo< $hp]9!R_@1daHGd@)*KXpgHq2b6FV7>O1&aYi/!mVUmC1Ya`` ].M=JYJAX#q9F'k-#:.Y<eI&e%J9LXi58=L/ UN9#;R11i.+9bD;U`(>An!foVE7lb9Ab<I#G8c6g#WoAc8?)fUh:Q^W2OK4A9b=P-sP"ttt]\djRc.AA'+Q6p5JE`<&L!#CJ,#PH'4!8qk5/i83976'Ys3Ak'&brS,HQ@pF1=c9r8K"sHs`a%]<`-g"t!Xmf7#]bpN5,C#k .\',-q$1R_9<m1fE%U\^4T7VUc,hSY8U?F2n>BTX$LlFRR&Qj"%UdbQ(2CIQ"6W$NF4P\-e,<OsZa<.P#_aH&SXJd^G+rpNtIl-4#AFM1&m,Ja$GNfoh=e>CRGR;G72S1&rFhlAOQH#85[.Q0<_FNk+F\iUYK'Kg+,cYkkO!Ad6S\<9`n`*AL:MH*-NMo %1AQIYZB"lPft9$<r@48lXt^mGQXA^Oi#@T5aRE7W;)ms"Hibk!m7mD<OZZl%2r_='"8E0:'FZD!!1F;^^co"cGA1%38M/=l&l+Q\5iOq!iJ4D7H']K+8jmBR5.ni)I,0n7PVP#0<Qfe"r>q.4K7$fiQfW@05*2M0Q,gaBYj4]Al#1EPUWAs)pd3/fM&;3C*le=YZF<IRDn9(#)T-_q K^Nr8\2=[)T6rs;,fYqHbD\Q=VLUOh.Ncq$O*2R6$ZtWXjZ 5%pPF]ER%++K[kb_AB9ei&hG!DG0\ 6CbJ80;Q`DP=I\o2/^;XI#HI#*?B=dCn#[-E4jDQ\Si5K46X4VM)$p#F?O\#'7IZcdYIg)o?fR^XGbNFPb*q[]GM)QS4b@cA*IDad[`0ZaJ.[#[@Lr+.K<hRA\JhY8"8qKR`LtOcFilqAee3A+a=j<FIE2RamDL\s5_%%X5&gK#3<#=`>'sQ!pS7Tk1+hGA2b`A'cs*&&!#V2;*;Jd\7a@S/R$8mgLpcdf](QGWYAAF;O":QIe()+[::3&Xms,6G#7s04PXnp8T-Dor6bAZQ.i2VIC!BCm&,D5j!LJ?/+M*i_8t+s6:!pb^;qM#f:)k4&!rfLUQ/-GcDq9%?$qtNFe#4:"*"IQPBZc]61@(fT!7/.T7 <t'tA<N`"UB!SdX7Wq<WO?$B6A>-Vn $2>%%,jjIb,M$`L-82!q1&?%W0qpDCFWg@U18f*%::H%sRL#n/t.r<d,SNsU&15Z/p:sWb@,kQfA[0q\q\#>!gg/?VeM"DHH6AI;+%a)h(ilYcP4<e#s<n:m`PUYmL6WJ/)ZE<IUel;ZHV]IjFFJA8=O@i\oB'T,,A?O!$Qe3plrcfEADaC%d "8fLCXlag_-F3o f^0[EhTAFd*o?bA=NiNL.m/4f49T-4XLLN\FLr&PA&:4q&'gCB<?rCI1=Z;\aTg^mk)mMD#JeY013GIlU.*DW,pM0?1o11*\N,oDGU8aD=fYhqpM&C6B1cF1;qYFHpbdgsrqX7S#n>B(lrq?$s3Rp<SE31\4UV(pb\D@eAq#p>ED3%\:o!((N)]]FrJrRO)"A)2i)t&LQh-l]WbUX=iP>l[Tf6MOoM7"f(:hfim0*@?Jio3=If%"H96(<8;7(M;/Zr!t?,=K"[aD:+6ak;,?&:;;me?f'7PGmT(B\`YmFqTaK7 :]4\Ap7$R:^?Xh0qGB$qQnjGaNR1]"Y9T4Z% T@pte3Q/??@4*p\^73Kr=s*FGJ5e!#/m33Arrl1]/1g6)jSIG:ah@9/aRR]To-!toL!hb0%I"1mJqi[H7@fT8+N:)"gCDr2\<AW`3q!)#6klf']q)P WODh:JMo!-AMX &s9ZA%:raO$)=,Sa[sBp*\`U.^^?J5nj3Z5Z*O>\Z)r([G.%e.QJ(DTm(TR(F\V^<RqBNZB>WqMk,^c$P=0^/noT/An<j9J=DG#WgDH2cN'UN<sfZ3jg1r<"i*jgtDe%_(e+*'[8R5_A^D]iL9P(/"b5c`?#ND"GGWMWY+]a $DfC'4l:dG;kXR)!>cjC,c4>r5OrQOU#M6,e2U0YcW;*1$P"ZM/1Cbl0?dQ^\A6@3:Z+-^nph]2 2tc#>6&Z@6[*B7]fGA[cU&)Sk0UgUe.<b%VLB76X=qo_:sH;f2fYgaX"8A$fVatHt$B0r70s^&UQUJ4O,<A@\sh*C7'_m%Fq[s8*DO=aE;_F=AP,bD!^e)*!C'$` P3%(C<A3-A<_d'B^(b1(H#Gl@+rgstJANe:DJD*)54&)H6AD=JY)VtJkl_6"AjQfEaH%HIaPh9DaMaD^r>FFA,'Xd`6epPmXfSsT )-iT>MAi:\a5+gl/.pP@DE%'St*+r;51hk6,/4TCUejW %7e$D4pQKGFW"r=h=a8^s.hp!?.6lI_:h]fD:i5=@m"3>^XHa\R9KU?;Vs@_%3-3>$H4L">8ljV"O:4Wje3#D<b2:2(,`RX*qj_Bm_%sOoN/dqZ?,,N3`Y2NOt2.dW8U\?OLiMXHe R/m3QtI%f)qNU@U;sfUb*<D1X6.IGq:C%h*O@PNNqnlQ_ XFfMYS4n7lH"Y2jTK(f 2+)aZVWsa9^ndABU:#Xm"oP"Z*k#/qoK `*iAd>HQBKJXl?p*)lf[K"UWl@BeAHi/q=[hF-*`<J!G[#.<;B/[o1bZI5(*:#K2r :)t(Q742hbh/6gdA1SF".>:JtCM)I7XD:,3%tZD(LV`d_>e@@>"LTS]ShI:!WRml\NG#cMosHE@t<1Z]"@JENC&=M7gW5t=D7Z'.KtN#r?fF/a[r-B20%J-,A&5A6N#<a_WmjZ(Qa@:Zf9dCb]4l.dJ[dFGEH% A+G+o4m`0#.p34?\AhZ9RJq,=(QB@gE%`sc<g%!Oq\Xt]a:^S[pIlN;[[k3BXS;!!r#GdZ[c?6*E1VSI)7WfGAs1rJs[bg(C\V++,_>K?;9k5Yg!:b=)Q,4jXh@>h$@g$GX"sH8]Wk$\qB"0*&3q,dE/a9g>*d^V8Rbrs&J[??YH"c9<@QAkj..T/nnaaPdQ ]s.-#&m/+,U0FA/lA[$O7;<NKN:M/%RqH_r[8bR>lW].`r;](S<c^\R OBUS@[U!R[-DTVL:nW`dP\2rc&@4=S3qfhVX56[:Dea(B3MYn!]t#Ai6C6J4iiL"IZecaQhHT%7MskGWcjWLZC$g\JrV^E#CBmk0\sWpb[C;%mgSJiL>62JFttJS_!I')O4fZ\4AlMm:7d1'f@2ZE-O*Xjfho)O)/:*.aQeF<tS[C4plfh3K(TI r(9sN?DMX:0#<e+N533P0XJA^BN6^l7)A)4(aDb')Sj*,2MG:*;H!aO6pQCIn.RI$F"66IL%F23<nY an[m#O2eoa#b9em P>AA,hiAFjV0mLH@tK5 '\F%m;g?AM]]&p%A7S&^ab7^5^%P^t?GKiYJ`"aBmc<g&`Wb_pJD;"C:cU6;5tg^U@dLFT2XN[Lt^o%265('rR76+;\L9WTleaf_co52*<QQANo9hXbjc8>X7Z\Q_KN\oYJ%F[G'>Xre>-"9R\O\_J*Yh&0([Aq0OZ%c&RYCWJW[,.KEo;8/oUC2PRM6-\sAqF?TXll'2^$TlX2OdR*W7PX0$CmK:J\MD#C*O:^b!*+rm6/ 6HUi^hB8%AmmS=cPT>9e;EMLUrFY6rAL`Ni]UQetHfeE-9bo`Z>!]C;$k\mtSE!ndgq@2pL@ i`m`fk#OGRcTeUgCB.'b^>sm s:Ib(j`%Q#. 5T\IldJfhF^kdIAZ,*,;8dnT7Abkag,]"-nL$nb]JCWR9L$n85 [f3'd(WTmHGr>$XeM4p&fd+1bTqE_jfn% kMPkXk- (Q7V,m*VYdCEZQrda(r1>$A><L<^(5U%OA8A&C#j+E9GWdmR0$*Z:JNpI/&hD\3cD>;@a\/)=joY+?"$%AQs?J_0p4Q<Ihck5UXW>:([Wdq#;/>MKeH4kI@m30otpY[5jAI*4g'\f0qiJ5f6V-OmQ`B^LL@AIK$or:nOHa.N`;KEh*cQSNYD.8h9H%HAn#`=[Wk(?H)?[>6=LYJIbm"QDW-4c+ES6WKS^P.?Y^>1\O6Y44l5WdA;<HnHA;SSYI&hSE%N#+/AjRQ3f)?-/i5^1[b^h+biU!9/C\Cr'[B0E>.=;(ZB";qm%i`^;mS?$6Crjg;;qR(Af\1ID\QE;cT^Bl:> `_ij_8>cK[Ut,)DhKX$NVGXl0RG`GKH+I/H'Mn#r?Y"67Pm+'3M7&FL\DFWN#qGIhK$N1>X\23%N#@ c4i$s,^>tNSrY&Oq@#N?*R%D$.!:QU^6B>pA^.Xd[i/Je+e+AKb>-=H(8jMiD2BWi%(72F>()`Te^1;b@]nKGrX1c!PjC"@q0f<RrSA9AA=o5X#[sK5pK#mXjdTWRk_>^\Ra;9r-CVIT2.XLQ\GK`/oQQZ<'WnA?@>P#*3INmY$R0N3-pAO"lRsDlts!8i0NAmC?lS"A>rdil+R?%WAg?/jT@L@@? ,3)P.J(*Ps6FHQ^lM<)J`B-K%Cr=fPLptLA'c?r.\Ji36@Tnmfb*"@gh_j*mN2EhM[]55neP1'#J[4fb!!j6eA!/jA]C]7]>mii%m=o/Y>,q^LSS9GUn$l@jn?<ZFhMIDV=5_AdV`A*UKJHeWp4#9#RDbQ^d3(L];J^OV @SgJ%\H[VJ^82cNj77pAf"sZUVbqPNF@#h7pfCJ3sQpr>`t98@ns`IbS:>mI^smC%q<Y%r,rY?\63$GK2(EAs^Td@6jg&#;T?K/0mtOl&DbiYiaI<GsE^r^8_3g9mts4L$NpQ_T,?60#'Wg98Xh8qg>m&)ms:S1c?Laq4U:YlM[>bH.t7!14F d?pH[HPBtA%9E%7m]AK4-?q'r+eL b\ZZW%j@#BpRI#UhR:FNFBY,0 MX)UD.@V&b<N-.T:nGYlKV*=46<lTV.]7pJ8ZnT[)OE9Qcn_<mGAUZ?SSW/DoL0oIr`%mXHCFAP3a9hT31a\)_WKS!d>cVAB!`\Eq %Q74!Eg7O%CDk'-fK9/49\5_ bP*M6qTENeA[A5e[MDmk7Ncj,l]a&\T>WVPZ,>WJiK'_pS(i@HR":0-T0nI\pY_5f7\9]I(!&otDqY-MRSX+th4gU)pG0KRJ)V!VGpTDiU!:9MilXlsO9K?O.#Vt("0Rcq%UaAoM'l;E!a[Lko%C3qUa2/fgC%Ako9!#8Cs!X"!fOk*(.s12S9tn`,SFBF9#n%UVYKTo=+FR#@C"r`%rH1U*o.?Ee^YH `WRM-kSJg-80T8+$ofi&gJ.0SQbUcAm=pY63?SmfL.ZL:/rA RH`-&OtN:T$-4Iq@O.r$++jHcbd^kKr33*?KYbt,'e9\GBAJ2;sq-+]r$@St)O ,H_EFUaBX1MbN*f/1W\hjrDLK"R#ia?P(-an& <7g/@11^/Jf9%]6Pj[1)6o$i.Fc#q"5+gm-3HPQ9gbLp7FOlY[j12JE)[>Zl!Eo!F#.nSdm!s(;$VL2<XMU5-Y/.O&B3S;WN%*V4IE4*efM.m8jK-VMe?Tb!O!IK9RF4"KS6+C(gAZ0_%+7;?R`mHAYg4>#W`P:.^L$0"c)/'G,H"H=08o_%^Q7J`4>Z17cX q9dWhZL:IFn5H@U,.-1;q%U)%cqFXQf^=[h5p*3C6_>OVcsm<$t#-(/g4o9 >U/T>>Le@?7D(P`R`Z)?+N`S+**I#1X5AA3IJEUa";l$>_G^4 G`\5ID8L$31/]a0V[qg+grWO*^sPAga>D6[hG,jX^W^:"!D'2WRQH+XA-AS+jOhS2nR@3b3ghn[,MH@sZQHis+d%A)=7$>IRVg+.r9.TT*ZSkmfMTg!':t7QUgk`b=(HD8ON?gf nOjj2^SPXoCV=HF_[P]cjPs,bH`r4]:2)7M[L*st%2Hlf&eq@ih+Fsop I(EV&oU.%";\0`@(;)V>2Oq3WQoh$F3:E6ai-spi^T$kjc+`rD!cWK($?kGN%?T(*]h?eO+T_E=)8B5ioL6W7<9)-r1cgW.XVf2Y3R[>+0]KiC8Bh>,C!$HAmQ1_8>2UTo._a[[qchmRnN2A^`BcgckQW]r(._m\g_gGt0C`e$GJ.r-^B"?<rB_+FM.HL8VOsmWiqcrmEXAI*>75&4q*)2CE^$F!f.;M.]>LN7P]_(^:2DLhTWH,:)A7c2sJTbDF*e%K*OL]<9"O:tWeV%]V=h)>r3!]l"pb3;\<e'dAJmXbD1-antl'2=j`NAfTbog'a/BkBY()=A?.%2ZCOmCdA;JI)3Dt2FDq_49aZ,`8qV4P>&!Zk*iUn;"A&'Wnl!=ghSC608;A@;mj8!GgAUm&W./c$F+AkA1J-P*ma>Qoqbn\;2<1Hbp;/,V^(G'c%J!8WF76%+/='$FK)!Dt>Eg""2/4m"ok<#`,Y5pdE'$&>-K#1FnB@76/(D#(pp))6aN#*;)ro'7Eea6qGsg"6qln-An'9;TgLrhd;:d9#["e@<#'AY6PeE6DnRL+jL)A7jA.qGMNN)s,_\.6EjDZ?.W*.#S,9Nq-_Y+57LNA;qZrB+4"aOr4lAbLcEA:Md5qQ.QrTlnsYJ\TH';5^F\EZD`<$8sKonrr$J&2DZ@I%Ad:FF0I)g`13t,rgm.Y8nA[.T!+k;kjd.#Ps<2JCCb$ksm0732;Bp*XjA5F"2G-e3<tMA`]ZY\$tIICnNeT@&_;X6S(f<YMfAdV=lAgLL@r6sm.HgRa-V/UgPaE):Z3GD>$rrAbc0sG0H<SkYpZH\8eeZ#+iN.$Y.^.H$G0a+lHll)qArK\69ESJf7P["Ys4ht(J]^]_)W,n-9tJ5r2W/g#"Z@:5T.\3L,.A!spDZ,O.OfrIIY2!ATKIpd3e*0ZAG`D;c&9I+G$"A/DX%X J-f+kNd('j4ND#E<;8EG1LE>bS$N)>L-Up?fbkQSjG9mr$f.,nZCYJ.o[S&YER?3 AV4&1-6#LKt7+C") \\@`B^Y:#i5gT0`(\E*Y!(.H%c9h1HkNC(>sV3XPgi$%.@YApoiOIm/=!4@,]9Y?p-5fN-f4@i.AIYK^QVgA0gI`W&*rI?X=Y?^/98'gIYnqVg[CkH>c-XL-/h]JSU_W<?Gt/G41DN&VAtQ\3E!TWn`6@hORe7-[+pf-SWU/DP.@IJR' T&2YH'_O3&[,Q.eV.U_a>l^#C5I9GII;?YteE`t4M?f6'!T k]rUol25g1I^2k0/q6UXhV16b15[cqs]P=n];5plS6BZpITMN,$I4bm0<St<;.n:3eI:_"),D&C"F?r2L?>aF'b:Tpmc^JL0/eg=Il\&:T 0JndFH$n%CUH6dCAa/+$SSGl?t/2YqPIooLf^_&/UtoL[WN/\,qn`TD\/k/-b$(!+2 TI[O@*1@h;scTFUIXHrN(+)<IV9B(SC)'%AjQi2`r9=iC)DbW`j1AVl.?j(*ATbM6O%n^PGi3>;jLZ9&oe'lo7eWcX8/ '6SQ3W4@bGC/N01^_Xh8b#Xi3rt^X1Co5OS]JrGQC!&V[bR\?++e@B:Kj:<\"#tDm*&?8bIY%;V1K,#E??rQEmr29fO!a1,hgIU)]U_6/X`6n)5rok"AXA`6,g;'p30]t$l!@.8M'XYZgAV4H%N\a1eG$Sg W!Q`WD!ga(r/tXFa3WA9mm5LMT"Xid&T.q.Q+VOrj#.(@.!hEYB*Ncq-et0bK+D1W_T2_Z-'r;d+df+7dNfC!To#[$RL3J[]\:3Ns+>?4J:Z4-if`L86=TD=M4ot8!7Q"N\+%\@`<N1#.,agY&r88.I>a5[0`DjbRiT/G2IkOpKZ`?)T8]a[ELKqFogA2P1ZGJd`(hA&A*':c8HM#3eE.sRcb#F<T)ZgU*A7g@IYe?/V2lZpKp<[qHYs>&,r[B3$Q7lZ&IW%T[h;>R;qV04CHjhKr8/O8IAn;h>M:5(((d1J5?qAS']+."p[kK<n)a6A:t-08^X:Tej<R*CA6\N;DW4QmS<i*&6Jffi 4neJp#c"CI"VKBDB?CfmEU+_RR7o70f-=A5q4g:1kAa%NC0]L1JgH[kHB>mZp1E+%;Lg%lnDsAMt;)cqgRs.^1_W\YG>A:QH<hPrN%>+1@H;\otrctFi96"EQF_m6E@W<Pd[jgHPjHsO$6*:]d S3c\:Y*T0Utr]qM`Kc'coV0Mfg-PE8m\b3$q.G-H]:>)S(oUA`pKfM@Y*o]Q3K5iCR.gec%4XOTf8e)<J+7=\<2Uo#IR!m::-% @%$;A:eqS)t( @RDj=GbAYn]%$H*;Ubhkm8eh\1fbKl4('*`05i1m"3%KGUS_G*0 _k,kTJ6X=?A\Y4Wdl]iTonCL:t)L.ptEB?Ab+:F?dRY[H=37M.JrRl"YAjj_T$dLtbc0Tkk4hRXTaAlFt/HcQ7HINZn;Qo?\P92q`si7W]WQtlC^`EN :akD;RZHn1-+WTX,h'0Z_s+<#2+_.4["s"tac_C-WhgA*gA4RGnO,2L&E8$Mf[mRiOj^!_Ec#cq_\TEH(>QsBk^J+A0rPl2=Q%1L+4j+TdUJ6)B!0IcqMfR&o`]Gsi@AgLV,-Kr-5l,*I9(==KW0CW-?Q"-WrnqM6"[%]NcPfP]nOkckft\Rj.?A;FbTC^MfgBhD- #;&rM$( ^b#)Y@;HJ#@2g@0pBj6PiOlX%A6A7R2hZPZk(8HfP+b1GB38&F=FO+%L+j +d:J#l\rl`nAbDEtdT/8@#s>l>f,t!.$L-XjP&Nf6Tqc h4eI<CH/$)j(#%LZ`?0/6Y]mbAse?pDiAaAOg'+F)@Aoj1=GZbqM]tqO4/`j JO?4e%:HFArISTng6,INUlXa&jXh.lKHQJsp?1lK('m$FZjdYm8&Xd!3GWs1AFVY='rsX=r\G\1W$ZR(;$%5`Z&RAAO?dot'im;3!I0A77D0tL*MK_ Z1bqE7=\QVb&sJH((5d.K V`A[h9d7-hhAqQnO&Z1]pGI8i' >sWcAEd:'E;:#6Js6sVS]eB9s)q`L,-1iNKq$F0[XXIE [#[mlZ5Rc06dfB>A:% <pf-"?N^  +H];[+Ko-IFhftgkI3GMHpanqiK.i> nb[n<FA[#Bj3!='TXWV6B'cJ,^0 i;QrWqq2)>;8kKDBN[HnaPpI;=+F*5n`Ttsr0<ca>^_&@ YOA:$[^t[#A=_QQ;VfHT=4Ir8\&" f#?QW>OiSEhrk @shHirk>9/berZoY>3bH<ci.:QqmDE' #14O<?Q7j+_i(jf=sW5t_Ulo^'WV[(tOIed,/9Tm%W+1bbG5hnCea!&n=sW)"jL<[2/t"UmO'+Ns$5\[s )6F=%k4R<;)@j%p<bRQW/,Mh2Z&L6G#c6a#U\(s6SU"b'EV<i0JPsF\OJPGRhBKI\,K<!EH(AOX\o@)'TE-6&.#"ZRc*fR^Jfk^h!nRXRoD&U)3JC=[F:=gD=$ch`KAQN_fMrg8m"K_ sU_0;JcM-j%13;+X(#P-.SjErga6>*PtUN>nTp`Xs7[2hAJO[H,bbROhY:RFqsVN+WtV^Ai*Z_8P_D_j?f!4[X0GJk<6O&A5'/SCO;:P+1DDH;n2O1O AADT8l,d3-=Ar*V>*IFR6.jc8CN+]s*bZMR)d,iH#P33Bq1ABaQWr<>R*;-@jT><98-^5CnO>p8]-G))41BD$7M,-hCAc'.Gs_DRC!gk>HSIHHER,+0afJ#(%9jJ`@QF%L1V;GfpAM:`;<1@Of(UC$P@(2TSLo-g)M05)F&*b7Y9o5A(OP5R%WL8rJd9Wbc0L.enUZ1F&[;ac7"!K,,NW*5]>>,X[>%@Ei37q,ro5LRs$#eLU1j&YVO\@A%b^MK._QBm;4Z2.3X$U6RZ*eOA7$bPkMd37aQEma`YiOa*QU;G6KR3X*q1G0K-Q=m1Ok#lE/gI5$A+-of5>a4\^%)$)=4-stY;Cr/]T3AHqY*,W\_K5-U/'.I6@C_A$M%G<8FD X0-s%l.>p5c7/)89RL>$-P>gtP]!YoWh?LMM!Eqtg?a,o0mMrYkjrf8?\\N)A]k#5&@8-%)RlN-3-!R;P70oq_KlO;CAAP<3JOr^sV:24rt=(q= $oQ(1+l%AK55\P9?t;BKMV>5dFHb,iG#<>#X_DMQoEZ+H;WXd;G=0+ Ze&@M\<Lt% 2`GB(+6TW?AB1Lj=2cTH9.9o#WG1I:e0$d`j"pWt'<b([?M.U]JEsT+!'o&oQdp;8d+3*%Zs)^RR5SdUkRNQ2T(:06e%T;"AA\$K)\:;^[<dmZJYoRnle';iMk&U!Q1mpC V/m&/,^!,<![=ABYWs3BERVYi4`SVXKpR7ZN,.jVg+BLX+ UrDb._$O,AB7nOiT6GAJ>A5C=B:r=1ULSDD]tHq$b2sYXAc#':I5 D"YR0=LWXee[s"f4O &-l4@8t^qL7l4UWlQ:5Opq%*_'b]j4Ik^_kH+K5(@Of_fhWAs`_D^2o]]=':KsmcPn99VoGCtCKP\73;K?l>O3gF-Ns`_O^l*e3h(FY=Ddt#M?Rhg^@`o>-OSSO&(G0Xa :Zk')</Ml\RD+r"M/Y(%Zt<k75?n@h0g>4ATV0/&##cWpG(AWj ?*kd5sqG/9.H]e%GKb*bi'Yg>K2bEcb6;fR'j=Pg1rnSL<!.=h.H2QJl\M_qD,J6g^6>fT)a?@3pMXLprO>^Uo4`ba_"i#tt'CAP*NP'Xt6tan_SpOq/Hs/N3V/PR9Y.>h(#njXVjDNmDSLEJtA$\V@C[>fcWN>3(Y9/(\,]Vf; 2p(b@$72V;  )\$s*HdfHp@j>DLD%N@gf?:_8[RU/O"Q[1jALA"[='/OAA)-i=@'636!el8[YdW/V(-d3>T;S2Oc\PR3QZ+7YGG6#d$ mS`#CnW9iANsQEoRP3ZU2q(@/AGF$8MWB:bObcRSOR'/;6iOD@iWh_M=/Q;fQ@^ P*ipN=7GDGqTC],@t(@%+1_LjGq"%HbLc9/IJ@Zl8sBP`Mc8C0\m5:s4Mj"gZ&Y3LhKI7+`m#(@r-R59\/I\$0$X!e p7W>""D(/k8OIt#3s;/0*7bYoik[F]4"6@,2'" WP@c5?l' J?J[TFE*d-oOSOTVGq:a%giE%Flg.bE626m-2i1h06BnFJULW#!20?:C(7D^9E0%hrZE&H^Ve4#j-W6<op\kV>8M\.!SdPG<,UA;M)Q -$[7gT;j,N\08e"\,;`6X4<^2AAbe0HZ`Jl]\8tN1P]-HI7pV:Q6DD7$k(pQZY7#OP-G %3co4:Bj.A`A5_iJrljh"J><-ZK^Gm.b3[QcPripbVm/EU0Fj:Dq$D`/*hJ\*8F8)'&O>YHQn6MSkmMdT^gd-NqPt m=$6iY6M7;l!l4CB>Rq2N=O;YSUi&bA8>)R9A&KJJ,A\sBCm< "'#!!I[*Vm;a4Nh2^f10r!.p:LjdF77_rg@V*XU<B`qfY/</_OlD?L:!,(N4@GP6B:S)(('TF@@aL3?t-kinE2cdC0W33'oI!%tBr?D?TK&NQ9@9^Z@UAjeOjrbgQMdA, :A\O4l@J_+'GU$lj2YZq`C1S O[0b6NdLiDVAtD9W5_]>%!t+`#/elU\2\lk.@Uf>0tR8$?qQJ_:kWKJpe['.iiP'G/,Z-L8pFOqo`KHFDsWdbG0n5ai<bI,GGX/bPX\IrM4Og4tjh7Qk6/$aM6VKpt`cbAZdfoij'kj*0\t%Q-[lhgD[,e#rltb #2KY#n#c[_oJ r8 O#/nM2=)E;JI>C?><Ha\cmVls(RBdo[KpER8%FWZ)gJ(4GKPZ7;6h\daAa?j$AA>`bVT_&"A+H\hW2"p!4E6CrV$*#N9.LL:5t<T%Y"W6JjQ+=F>M.KT#i;\bJdqR]B94)i0;I9)/;_5_SR"G4T/Uq?_3WmY*Yq%6K^dt:d59p`jeK A7Z^U=OOjHR2FeG0OT>S=mT<Q32rgqA>-A#'Yc7s s,@_p"Cb#T>.jI/9:8;cS5=jsSXE5H?(.VlG3CVaNG(*CBam!?S5B<bkE`;?\?H)LTb]Ro'1PT13Uq"HKEs)/(/6cM&O8X'p%XA;8;5bgFT9H);UYP+BiAUAJ*kXb]F?;!o% )@Omc<fjd5@]3N[mfCN*f_$%]j(q/W 1f4E`:3m$KgSiiVR"!/1kOscbi2:0B<ioZfAbaQP#B3'2T&FW"M8JqT)<6$ZR61N_WH4NP:\f@G5U;r'Vt<?o_`0dRW`kr6($A%gg6=E<<3XZDMNOF(=:3j/*LR>-Oen)\\p>"\/!i)ka$m0i,8S6no/o-glcW&PAcA![7-A3DVSAA9js5H_.%CH=XT83\Yq^+er tWe,P:FIFHiE=1K&;&5+@jj&N!]%i\Fq0sD;9cR ZO0P$4:?VT.;hFi_??dcI"pDeF4U.(BS>`oqn]VA:TksLA\OW18p^FJhqX,/F&MDPFm1GfAd_sUVC2P DUC rMl@APAG9J8+r*(JjR;!7Ddh:nN#'BH7"Apd,iKd(&LW^Q*A'W5$=/H)Mn\2a'h]OXO["oUSI"$;c]Yhds<X/,-ZW+=<UH['eZ,*f)KAm*3AD`mJOB%*4IFq9``(b:J37#SEqm:\&')ZRcg]G+\Q0t[P)#Y>U82dWk'L.ic o"Wk+<:X"N)e_DdrW1_OL0#ap []DiN\JjPe"lRaZM8r4+ag'7=*4tNbea=?;2HK)6%?tD982!sdEd*VDh,gqGpD=$j;q\mq]c=r@ .\Zo+Gj"FWL(@/4[T%TQ@=!b*<C[! .2M'*b]!Z[bp!3G#418!]SI5VMq %qEo+bTgA.tjgkC!ga3S1CYc$WNoh#fCa/VUs9RIs/TVlaAXn,P<qlq;8f;9"0!5nd78]WEHGfVa8V0apq(WA9fbl-Cqr,C6/,OC%cN&Y#]<qWD$WKh)X(.r$i5lE%Iq`t8i"`d# L+oP[RPJM:-Bh!!lrcL_]Y3VIAePj20E/_*cZWA<Ce:[8%*>! )TK$!Ih8)i&iP1HbDk!G@s5A;RAKR+JPgi\Y1jK1l&5<m\WWZqK'DY7p'PrN)egc`=`dp^*"Dtb8+/&6["^]`Zep`oAb<YBeI1$NkB=^-G#cZW;o>^50S?LMPUI]rfD&^6>LAf5[7MmdRNp?/!:!`3@ @m=/9C3*c'&=Jlb8^?o:`YhO-5GrBbqW0S_*:D6G'AcGjrds#LI!^7&RT9A>"[=bOJN`4oW7f^p`S^J[<(iA^7.$q0Ad9s=6-AcK4r?h`EXp9(`g59GJjHSm%LIU+)O` +05ZHsoZN=h`'"FOc:T;@_7CPD-TWFg/7<KsY9S-+0;2q93d?_%=5C_d*8BrBe'qDiKJ.59j,jj)$3Va/H#-r$@$)s7it_K4\GFLjRA#%@W% '^Fi5[T&Zmn:D6EEp?FQc,*R\]F,\GM*amdRBO:"lHtU $B_r+QK#KSlk:N3oq^`-Fj(PEf%BK+Ti4]RTFNgM>UUAQl^&,_)IAt(7^3g?X"1']/&b>FMD5p%bgqDHd'+a`\*88*$BeHJt K jm.: VL)cF_=R<IK^\8Pa-)mPR,n3bNE["S8>^<&hV'B <.p0\F'E;Ze?3+C/g@2-^LPA%-Wt%Mn?%PoB[r:=U48X49Tl7jDQ-WC!LC:%#5l[3b]>e0TDkC/Kqs->A2$7HgDU\Ob=*= a(%j89@-bhMa9GMka%/')S`S0@2kgA9MS!rtX65<E/8o7pAa4gPW$H+s@[7'a>JBEmS?<I#)aLQWioZ:]dB'$4lA-I-"'g/mN=OU_ NG5D[r,q;ri)e\Nei^0iX AGJVq0q25V\j<m ("o#.?sdk$XasYX7bMTdF&hS;ebA;#J)(8Q*sKDI;)]k7m>h7WqqkJToGc@S^qK7S0Mi.<iab,b!kr9Aj2:rLd'+:76mR)r9:PrPA\8]>@^WI'Lf1NZ(%hA^))K*%mlBs7VE9M tNi@9SNk4F1ah3?<`WWX!^:b("<!Z/7L,\;7dM6]a:MXdKI#Y <`04kFZIC:<Q1>rKN1`qT&[))Pa%h#?\O?s<IT_`'M'^tB9+grJ3'/<]d&Z]O.n1A WUBlaE-n-2TDK1h+)ig8g[K <]]R4(#9fM)C<]\HCZ1YdaJjX?+K2#mGha3>2#YYOVBE#jcI7CHR__T9Qd?/Gm5[tRf8tW8U'id fS@_5?".$I9)1Ve?9J/?hL:rHa>f<>qAn`Ug?i^R=2IOYq> Q-WJa_S&]S*=VhPS`-%pWptKBhe.?IMc/G3B/<o9kj1AIKN3(#l'?B4k'/+nD2Xei=ZbJ\lpm!0>#m9lI?p8e>FFpt]bT6hP,(b6o6=''.p&rYZ]niT?L(JV.1*I#qm$qGU+@1a@cL<! gk/<BlR\1Ucf79P'EKVCCQPq$s@EoaAjR7XR??!aSH!VN>dC+IF"Af(l1J6PA(O?[RbhZIp0IFooE-%j...DOF&]^l 7J;6pC2CJ,dd[#W1cA'0Xl!nH:a24**!%kF6\S[cp!PhCgTLWWPsr9lV.r_:HUD"PWti<@6R_W)LCkM<kp0cnA> `fcTl.;1+rhbXX5^=<Q_<k("Tk_4JC^hE<NgA[$drM__'$t#\@Va4LlN5A.Gq!7Wj?(T9rBF*lm\n3-+md] gr]4X?.i1()\ei=5B4>(Ke@^b')g,WcdX]c'j)@KIc\Ng'-G1@[:J%MJ0E<*&"f3MT*$fVTQ4=:5l#pAIm+ns-,:R(0q,.ibo*21jq`5Mn5"UXX_n/J<cg6c7j82V\$H1!mlYnj7M0AA[8X#)=UG+;Qm5G=`5g4*;j6q#q/hiOATs`oLIBa.p7][34AJe_r/q,N(CUMO4Seg%:(9s:FqBnHLm;Sp^HNf%fAs6/DL@GS,=F2<lY+b+4r."IEdri4J3-e$?ZCl-W c`+sdl8-'."@;dIr>l0H53.1=>IWA?Ac3_th=HtF?p-i^VFsC]c)4E!>+AQN@@\?IH*tN:NBt$^Ab=?jj;lm;Cl[>DV.MJjpeXd19lD4k28tCO)^Zm7kZ'bOjG-Jnd"A">-m;hHB@g)p8ZW.j4k^0/k7DRD=Yn0=-PD#]%5kU@eK.\H;H59XF[(hm]qV"R@"iOA1M"]MQR5, 'c2=Ph.2sbD+HmOZAp?_c]5mOg]OM;1:$_QkaS$csUnd/)e2iN4>IN9UAJ(J 0Md^]/dB3N8"^q.j'bfCjOSs-!rCKYUj#;_o$54D,Lq3H0MB?ZCI*C6.%P>ng>EW#9h("sMP8(B4l;!oe4)'&&,Vbd;P-%VH8&q:=/e_(4#4/:nNho\*6BbMqG6)56F>gpEgZK!nEWS,T?r>,ApAKD9E lr/1E_Tk5o#XUdGYft`5194^WV[Q@;jA)Za1NOQ-a"5;LZ'YB!6RfA#sZVIf(\6B\irp/KYVa[N*8m8O(MK9+JD=m;iF4VF@`7?mhKA>bdE50AVVJ6Xt_#pgZ7,U"B#=]*?mrF3MAYRfA"- N7ZDanqj(hK3T``#mfi,0 0tGA(LbPL0k0DWJ8XS82,b+*YF;#;_&6-&Q]tF<JI"C!>MafcfC/\r_QIdc kd0.o#^clX.E=3<l:74As,mM4A>'B]78%oRLUbCd8Cdit^GnMsE#pR:=qV0% skgZGnOK:scEd30<*f'dem[/<I$O_``-EZ=92ToSFWH7*J3o5<!J(q/)8q/1=YVRBh\An'7t].l%shN$tJ0p>$!B!jS<c)"!AJMYn^tf!jB^]W[,6hH$/cBilFHDo96OhLRD-bi6;;G#6B[N`KWIts7?3Jg6 SZ.ih<2IrIS93OABMd(.A\d"8KoWECE8_KZ>RZah// SC29rRbrk"!A.i%[!Zlg:&O6%iWnM9 8^e)K$` .G-."W,QN2rnGm(V'LEF*IUT1pmH=iC$@jp!D@&C!nDr>5FOj^N!5%Q<(jF@5<1N7^s<H]@&h*E(La )=cS6P@O[%_n`j>cFZ"ZpkQ=UKL`QqZH&"6Cp'(Q,H8ooqZc.\WEl1 a<GHjI%;4#!Of%KUc\T2o ,))^fP#[OhPE$(3N.hBU(Op0'?$1*B7"I)R^IA\8_G<*j6h>UR`><5 Y^l,ld/f28MJXjV&$I&T>$9g c[K"d\mc7OV#Z*Y$M?`Q(QY\,_\/@r5H \McYaaR#CV=JK(A*.LI_aRAArY?AjK+R= Pn%t'3dX&ZJ-YA9p(q')@2F:GVe9V+7j.]pdMrT QF1V:$*`@.?atU6Yi;0+;oNA_'Va0A38-sf6#YZn_J3WIfF Fsh(TE64S5-=Z/L)#<TWA<e/9Z<dh/<r"o[B;"I[EFh4/96tL*D1K9Cn TpCk_?lE@Xe;bdnlE,Um A")0$AF ^8W0O$oX&?BLh78NfoP%`!aa,kE#S%DW>J7S.Hg_oYN_e--jU2oaK=peMh`Q[$D)dI5q3tA7VDD+,?iG=f*bs])J/8;qOam0mcO$FXp4jQqN!iMM'KIE:l+He=U[8o/9/sLtd[c3oJ%:Z5hVVZ"dO1$;idosN<MhfhQhk>Dg,(A'F!NfeY^O!akMYg*SM??f73PL6.lfHY`r_I]-`V;.\A9j8h0*Y73ZUQkqo!Io%i*+hO.G@,/d_%'FO9dP@^D"l&Qe*-[$!^=X)tKAH$<sLrIm3lmOC&m&+M'm^.*tK3Q4r@[Irnm$tT\=\(r"r3Q40F=R(Wh2<`7YVrjP<mXJ\bgr>:TAK4KQ"MFTAk818%GnKgdSG]J4p\8K2ZN".1om'PN+i5)lI1lhK8ik#m3jVY'W(+!%_n*W@.KUQ+Tq0-JE -7G#gd:ARilZh9/>]0,_:kTKm!F_oHrV8Y<*]D4'tSieR&AOkf_?J'/o:qPdReU)LmpB j?;In4k?[tAOi+DZ_7&<2GMK76BM`qMUc#1#^Xi%(H1J^OkS;a/^ANh8e.=-"J.f0\P$,h"s/,sW"Oser6QcaCK[D<^:pbTZB_$q;0FT//eqJj-%KFO37,%`6kg6B%`]M?"8cte0V\*W#&WL9:5a+,-(h8`;;D*I@:ZoS%9(oJoYfGoSgUJN,N15"(I/G?G$G.t#nspAmaV4KoAIEQbi-\4R?t>Aq6kVE>3X"XFVNn;<:;]r%'p_N[pjjeJ]^W :(&NdMqg"(!'F*PoO^!\f2q!S]\Thf+s;9AI_3-SA@k>p/[Ah'WtN7=#f-+k(+p5]e\^jQB6-rDWMAb,+K0d=WmR.><:Xsg(fR\tMOkh!5'L5@BsTsGMd4A+[ZSZIp%/$aPAAc*A>I"h?d:^? G)snhb2eNC[(J8=I-e.nb2lLLQ#TVNLli@WnK`PXVI]M[ki^r0Se4?W_&9M%)\]r/0lcJD[Rl4rI2qG(_]^1,`_RJ#YA&Y3JI,eHKKG@p2##LQX.89hjBo!t_,MC;;I!TWAp>!sjf.^,+sZ=Hr%N2o+cSk.9lg1d!]4#MX6(]ReFA=!%"gqCc-MW<TF<*\7"VG)<.WJYbD8\hcpDkbG%6cETS0<),EKf.W9/g!Xat@lDs3)o'#mc^H!S5VIC lL0Pb2W2(&krB9NOK$jLSe=gA%@qO#$7V*V[L`AFMPLN4;Mt54:A/%sN;]snb_1#^rVWOAA$3V7SGF?.<o,! b1W+tjd'=q^g.4*Y<f&ekgZ$T<tE.H.)3QpoLD\$aBatR%P-?("5^]>,8#C;c=th*btBtJap]K\^+lV?\>[;Ap8<&RsH8cH`#VS^J]?gIJ5lo'9Z,GC@f,AT(>^dS2StQ+mNQm0e`6\_:)?/Wr?,_^'ea6XtD2fY3$hTp?eTdaG<+,!fsOW1-^B^4:8d++a'ra]JQkMO9V#V2@U_YWLW0L)OSU is?CXFt'5KA:p3ZY/Og!=ImOhfIR4@Ebg3AAXGh-Xkr>!!?CbmA;M$=]<'C[W.i=B+s4"RG.)<OA?+3C3# G-oKV=^gXD(V#U\UVDWJ3jh:[C4t^3P0l1'kL6WaFX\IGFn2"qG(NJ8E_p9Vbc+j6BGLK8g2I"HI03YMa.k2J7_Wm;1)4chr![$5D)jMAQh(Q56<7CD.ad$,lMkXDH$lC2kgP9YM>DcBm(Q7PB#I2Mia<ZLo^hb8^^>Ys?\VeitrGO4@U"ZWW+>5V8/C#.hP(`P.9,&S,8[6IO?BUO.oU[*OAmm("Z=4_) RX>'AjKETf+?Jt`28%7n%dnU3bRc0=>PnWVZ0_j+/a5&kI$G_=Nk"nAPVWhe0PV*tIZD&*-^]gpV0E1P4A]i,DH8j*@-@=W9'B2DTA\Q23k$K./AVc':YSZ?%dQ9[d!i58q!6$qP*J-.i5JAj1[1J_`lK\6pIhQ`;pA0'"XDL0#0oV;N[mZ)e$qTtNRZb4AGH$S(J9=ACXY)jG%^ggr@%IsTQkk:ThT`@^qJ8[]qPj8$.lmTp,H<71TW@ASeAY:q.[0mZ5N,sA;VkN=6?j$E`[SPR 3n*:ND1c1-L1KU'-WPH6QA+/E_bph'83j;eG**giUl6ASo[]7m2[^T8G6jUUd@prbCrAOVlgIU[9_ch<mjMA@0r&$6Y8f.fm,LJ=Ki^A4G&^'r[*b'[&/F<>Ge;^X@ T.a:+&tptA0%5-p#@#$>r5T27#jKEjFHtS15pplmSM\mO`"FsN)d2jm9KKme *OTa="`gABf'/O=2@,e19XR&<8p:1L&U,(@DBYcCGOIeD<i"RT)8*M"R#%"[?"PE$4!a@630<Ib N[oP%rQ6_Aa%:/B=;5^-+e(s9]9Bj/&hXX+XK n.ai1k%^Yc((gD:6qTA8O5(j H0"'[$c'XIX]_FGdDI$b8M7&f!X'fi>7ajB<-fbp'\V>q7n>o8fBkERO\?Q4ie#pFb eSs)QTR[pd1`-YS=Jk/9Y**^`p#YPQENmk6UU-"]E'ZP?^,L5SlthTnc2_lKd_>imUpXBVDmRbd5r2-O?G8;6=,.$CRM<KfVIZZdPeG>UdZ9RVs'oPB *U9T*&Hkf^]Rn#VHLZqlh/JJ&Y`At `hPB&TR"an*#.J0E26`+CW=[s;^?%gebsV+[^`EUZ'aFMS!NjmB<oR8]8Agi">c cAG=VO+]+M[1rgR-?5lOMiXm^@0X1"7j_=A& Je2mMh_>M'mat?$)l[S'YjOsH]l ek+Ls5l8 cP,=`MW@m UoEYnV^MD/A>4mN=4?S/Jf3*>f%V)B@(;A$Bf^IkcLAq-T(f]i`7i6Xf:%=0U>X[+'(ac:l7o#[Pp;;`&D+CLq:U"/k<";m/K[E/L"23TMi(bf2L6A0'D3*B1 U.-]Z3FHJ/#@9'V5<U<[#q)ss\;/h'q0PYFh=?L=]W:\b%I,bdps1\%17;.eWfMm0DD=;H3hXOet'6/P<(/-O]8\WRC\?-kklr;7XPBg"FNAGZt5M6&`mUHgLI^^/mG7_5I7e?<baYm_"q$/NqMU5"qMM-UGFaHDc?H8Od>A;Tah)q8)4]JBp+%7>nmhS?e79@Iq/C*J_5r@9_ZdsVc5Y/k`BkgialL8::XP*%V[cg^&Aoje_/c[ms_4<MKHE8:4\X_.TrALSj=1>\N3`Xt^(KCneo>^ogjDh,=^/RP'-=q(!%[B54UpT,ic%K+RcrXP9sKD(0/m%>ZA:s==@cAdm`aT]JIC63Q0209[%MM;9:d.`tnKqFhg,3(YO4]4 =@&[?%6VWTA+K=A%`S/[jRA/rCA3#BBhAdn D8p'l/W+tiilb;=^'\GRM(8b"I.[?*VF,+%1"_#J8mL7EYJ#1T%Y3G?K^57Xmk(TQ/&Ajl6^mhsR0CB12Q@$(tBiE0YB)Uk;A@'tJYCab76t1Q9Ta*0f!AdV!5!3%;K!<GqsPHlAZYHP6^1``V\\C<Wp/s=C8MAO?ER@:Kn%5A.Tn[B^6nZq1WTLl2?c`lMHF5_iiZ;gaRT1!WA>b<,N&mO%TdK 4bOOfn;m`I_/<?>:nHcOq]Uc:3ljjJQop8strF,cY'Z?ME[`ps[+adMHJ2A:?)ffMG@OHf6*,W(kDNM:P&#"f=)e3h%4^]f=0T]1+bapD=A60M&l'b^4HU\la-I-j<`A_"/V#<Ab7Jps#[s8A(:9Q8#hDAO8rVTZ]cT9&^QjY,4T !:N\#"apZcAn?&T+f$"AX^X0(t*WAQlIc[QTbT%k#Ei)Yo\0a%90(J8fDQ)qnrr)jgJR?L)')0l?/$KoY8#N7r]ekrqIHHj?Z0HSK8NV/@pGo]b=LF?N?CA+5:0VJe;'?=hc+,0k;H,A1E:O_K+2Y.H"?N-`XfWfRW:7+,*W2GpjC]n*oD9i$Dh"[7OY<6n*9qUf0q@pG+jDa3Zm2o(\9H&fpVa/9H.3;fm]JGeYQtG8Zl5[[KkZY6f:2QQA3H=.`;_66IWsh,AVKml<CGB7/&QkF3dR;;@k\5L_3B&;QG8h'O_&].=h=#n9HJJdCLA`BJ+9T96 aAgN 3DNN#7[XX"E<ejGt:.'rA&].'-[=HPG?D[WMPrPcQNbm3a_.=]c[0LB?JT4$j?.`s-(9i/3WA@rmAi<1dF!$*@glo>h6r)_Ti8b)KG.K>6ECdLQL;d`<t1#K%+kgDC_'le24[qs8T;"a?e2c&]XQtJI16 8ZN-pGA)AcR'M0Z0qG]CGN*eMcCZUMRf'Jd,r4rA?f%=K4?DPK)%O%nMNn02>VeFI`8=)`Q<EC!$^.`I3/#gd^l77:8Z9bN2p,m,TVF3P]%,,ND,>h0ejFQjJckrf,><6bBmIUJ+rZ MAs)AJ'*[qSIC_e=K*1P0G.nW_A]c%)H*HR.-.g-oO7C N+Ie%aZ]_fDW]:S.9TZcXq3*ih*a)U6k)iqoXs\"*dp#U&eM%A6mVd2[bp&`r$'^UEi&jSsWU,OjYX4r9$AG*r^Db71Ul1M9m8g6+s) CaaTI`9#b)U1AOY3ALhtA#q\_+]PE2TiW'6aZD\HdkD)/U<D&l9i'Hinl[%5/S'3^IPe\$(c1]PnfGtqWV"3oqjQX i+9A+<qe;gAC\$ONsLdLr,G4ikN#RG+#$A,G!hV@t-8Gk"*d1Y>p.d++A%I^#fGKAW]>CtGt@A.Qj%UKZZHNnXer;a(&?Bq,]W*ot]P9e%iZ@]lXcdPU(h#TA7HGT.E8R(h;EB9JT15I]q)XtH'h[0IjLYE=/RFFlcVS)&GK"[Ag`+GcdI?tTD,_XG..XfWAl)gT)7dOFFs3jC#ctjk"2lpNM!Ui0$5H@ja;XZXDT\FMh-m ^D%AIc;N5A<sr$+1Q&[GsOUV77rQ"t:$ZXPqDc3l;7H6nn0sEUbd!Tp.rP8'B4:Hsc=%^.bmYfs;jgILi_=0L/n(@;dPU<_U5'b>.j%o%"a>#'h:kjq-Al`V\]Ih H>:F1hd,tSoPac]sc\'j:4\Zfo<-%foa.F%XN@]ZYm+SIFi3f2)prdB/c$U1)["WitMkFS5N?=b.\XXf4D@[A\\jpg8iNkRCch?pB@R3$:G!X'O%-B!HRanglMWA#5eaF2;a 2TCs_<CDPW_>>cEXqFAo7-<l$ ?4krlJ/q]K\Y)j_$AdU"3'P`AblRql9t06f8(bRC&*:[#E5c6cnNWAQgS7aSnn1X7rNM<c-tV+Hpd`MN$R!AL": =LdPZ[D5mg=%sD"TdL)m;AaQ7P_-9A2s[.'TnY'6"C6aFL!a"G][8>&Z0U1iOHNSG BShrT+_I.=P0:S]oA[]6&,W.`4_+#j5G7Qk+67og`SA8X5RB1)K9WG\go0C_ao<m$^:m[JAA4RiVWn_V`c/am _]F#-;K^ HV\QBI4UD()0+e>N-2sI<b8G)2V38bA`?:\Js*gE)E#3p@_Q!\'Ghk(?!ek\S=JFB+U_P0?Pnn<qZMQY+M+q"[+Ga^<<d25 Z&SUg4PQ3F1?<KG@kBY=sQ:EBda_oNV<OF7D03FJ` /Y)D3m1d[7@JPj)LXn8YknJmPGqOEQo.AAPCI;d9*<3eIiO98tl_[]m8LaAhC';5`ta2<H8Y+.*%GDJDA,6[+g\@dc+3c[D:B:C;jr-0fS6mJns=D%G'Gt@Lo!DRPV*!e=Go/,+dP>8bQ*>P_NM#%ie,fA31lW[sYn)Z-r#>4lA[C@Spt9bG0YQt_;1$V%O\-Srhr6H?jM\GX"KX!CpVK,)Z)Sa/YB6&^i4TpU\FNZUgPQ#`l5jnK]-.A*l<](I1T)M mQ[TM\;AdEF-n'*f[o&=$SD`oD#*7Kg#R?0'N=FomX:N"m$rM <qFI+S_jg4bY7pAf=UP6`2%?l6Q5/U2dH4_]^a OI@JZES6Mp<1Mr6\[(/J\b0MSRHDh$6pHA![3r^#M**XHJo?X]%E`Y3%6E(BZbmUht6*di2T$DSSEg^8fI`@D#/?:"IMNW]`Smf$2&R/P<qoX]sHKQgCQsMpQsKF4'cgTh\@DZ;SkDGjm_ocfF_4qcWn54/aH\)F+6EQsOOif4sa 4Q9'LTK_e%]HlDr#tL=\akd0A(p*YLhENc#DNA(:t84FYn'<,Z0/NqP4E7#XD$T;>H*_2X1o,RRolm1@Pe05A)X[3Asq<ig!'gbhLPd`1t_,eA^O9R] jl+a=jlE$g+k<"$lm]FUTi`RPZ?3BUU8A.F0lelo#drgnH2oJ -dd6*>n$r0RHNDAfC`JoA!e*.E]NQWh.O8CAM_Yk%s0aaP22;=30;9p`,liM"tl\@(q9K\<%V!ifKFoh0>QWs)RDAA=Ra\o]GE"3"T[2iC$PL_ M, TFR<0G%iR[j=4EJLZ:iHnSsAGCQF;-gd"'f^PI3s!WP[gbp\p2K</_:$sbN!V=r2ks&;J&Fe$:OSY`Pal2-K71mpkr.)+>g],fl(NBF,k;l[bE'27W%cKWL(J,8RH^PLqi5d[&W%Y5iU.IH5\6PfP"-2htG-L#W8b^"J%'XB6nV:Yk7'bE`sp[^i"l@kZ@\*T<pgMMK OEP@0;5<_>0jnA4(]_pf=R^SYRG+EFQe[V&i<c:NK1.6ACM)NUd]&GR`<#1()LtS_+1@kOK:GD3-9+77di^Y'>W3OMp!VRghd)Je+^<VM5=f^)qNs3.KDRBCM#6gJL?:(e1@M\U.&R2AJtbdNO&9 [\-T"p$<H)bdbVUPIIogC<lJ 8?'<oI6oigI'jY=PLB)`CVY /K2rJ&Y`CGd]`jT<qF!%''lW;<DYTq,Rl0Nf!jX]GK4r5S-9?b]TZQ?/Vh45G%)CE4Z"b*@ktUl[tUL%4;`;)KI/G(h/:GW"GjG.2Nsr79_+j_(#f)l7kaO+sO]j^jM>+PLQ$Bco QOiA;o;N'HA`eAV+654S[o4[>]AjcN/g'VJHS9Ltn7b7*k<h[<o<>F5\\`rkP@ChHLh"]W8!;V8C)&^%qLE?Mq88IHbJ-eA$;+qOaB@4kCGY;O=d8\.oRU%s[]O?\D\0JO98 L`imB\!#rHo0]i+02k9"4#)5:% A&9Q:,;sDZk0[o(GVlI*T-W[-G#J+-@r!,AF3NG6OhUcK-hXd(##J85GUGZp0Zi"9_Pj4^e])>UC3I8T+Hol=BE ([Y24p[<]CUcnR-,G=hO3WH`WDo]5;`=EGi3^d7aj#G.r2kEP6S];>ab[<d%0<kE7lJNQF+pboAUf[;< l/&<gFY(WgTsAh<:[8(i]^@\,B\?($"QQbQAXA-A._A4<^-d#ge4A#G#@?R%k'JS:V!Z[D=0j>3jh2X1\'!2D'sl/*+oZ8;&\"VXrI);dL<t+HS0(6 6!^=Zm+] :)3VZOi="O$Ynbc0]LR]d) kS=rgq4,mmKa-0\0l1aS!f?rm)4L_Bp4FQ^\)q;)F)jq3)XJ>A%d<WQ#&E4E@0"<Pf;*4BJ.^kfn>\(c?1; Qp]/?g?:.b8%J!N`31"B>Or&U"dHHk-+.`=27f%IT+#r:$0SfoeZ%p7[4RG!3GTUmO/JVKYm=5aC$WQ!X^@"9li>0s2qj)2G,AZ6%F&N#lHlaA (B5r5U5*TX\LJGd1!hOV`]YpD)_>[i*T,(*_oi*"b6a-am,)Y"nK:-T#Eq"-l>R9TSU310G8h?gm$[7DgXt4B2i7fB+IEWi`Hi<^lRseL7U>f@*+N_hAsH)J>f?[B$(-,E*58/44`l%/9]6c,Kj)TfCDaNAROGXnlUaN=WIt_!Y9b5@@?@57K-68'\0[`cnBG.YRD@coGCTG*&ChORm*2%a"<'0s7TKC!hp_`.A2Vi,d*)Zd Iq6QK^KSO9[n`[soc&tHMWD`s=K]1h ?BbJ?pH.n>A%CIWKNsboRXU"/p%Ma"iVi`mA V<a$IW"fdA-np8qbLV0P=UN(i]i2$cr&%&Ddb@`i:+jL.sb>'R)b^e^Ge!iqH`dqTs@a6\7EA(lWKVHW^,,2o5@moD^Q4\GN9YPjq7K4e`AadDQL-R]3/b89]MJ9jf7*2#m>=*RW&Dg1`A)dAjA`^&]^,<VUqairOTOY9@q%CA>OV.iYWHliSEStGtBgt71qQY86*KcG453U//XH5:'^R0<[=9h(IsMdA)$%L(R'mAW<m&07;O1 N6a8EqE'ZCXkqF9@DoE^UMGOkP);plN"H[aqVD0cg+J S00;(DcDDnA1VZ9;484q$C5%<ddiR+TK>5BRHkMP\5dm.:"J?0]+<SJ>b+=Eta#\XFb9VpAZU6;?1S^VLWq$\!V=./:2\+lnHEC=.oMSj/E72a7[kE1ZM$ h;m1=lfT#32?VZoCDnK?EAA*MJ<fMq-j9?f6i]dP-YM$I=jjPD,L4@GU0P &JV7^5sb=Dqjch%B<^/]`n!W9s,*1ctH.o>%MGB_l\<&/P:3%Me(rQ3N&'@,b@>KGk`4D^h)Fl$DmI>L:J>^1"MYHK.o^!_]!qj(Z[=!'3S._MeE1GdPrI#i^#jGq4"h\DZ,?i?jdXMcI\MtsT1:(PG8#?DM?Zse)Gi1OC1W:d`69"akP7!>:PcQc64aGhpcnC/A+d/nn@fQsG3D@9+i"GP?G9[f.3W!RACAqVrdn!k/VWJSfoh;f5C!H:a,M@n\7_]oT *>nDGh*r@N?2;9"6cV0-.e4](:FDEas<%>X fle&l=!C,q;6dNIU`;?C#[p9*d+'L<On \ A@egA;=o)["A"0,O0$C46I,i^LPTlqM_k-FYq/R*WBTBAt96f8:+if2VjTP#dh BimMR0sgI^+ik^71Y;h,d:EUQL?Er^O"\<(gOoi!]%`3+T^FtsK4U(\B7kps $_k_6g,VrYU%V?A@Q/&h]64f[L,l,!)YJ(;45?d/i#Xf`2Z`1-OoXjlU:2?e:L<E/*$r++T)cX=Mf*r`rl3c@i-NA6CC'HjgHaIPaqLG!)V-:;&Kca.21_[@Z4??N-4p.e!b%B3A TaB_*'27 Fh%&e g-9;"Yh:as$\*Q)@gsV2Ne9Kce'ANN--E<O`o3R<nDi\R4(<Iqp7$qVtVH+M7JHtZ9KR=YGeDh7U#[Wf27Fb9sh7Vr(GA/d;kF'A'!5t4VpN\kOc.gT$D\c-4[XIY4*jgX[HZHcAA$g\k*8%c@:=lfo;#<mCjVrLE<k&BN??K[hLrWn1$1Nl+1#*C8ZGl<bB*C@CfF<abJ^PQ5@ D H)MF;2Z\-6Fd9f*KUSpj>N_aX;a.e2PGRkcVPFIk3X*q qM`"jRY?>#E]"-`YLK[C:QTa/,8p=1J7_rZl7XX-\rlM0;$HGfZSt;_Pd/DPlGJ+E*aaO!X['htANedI)<'j+s!KKh@q #VO!HT3m\SF$Bt36o@0tc-ZYFs?VnN2)D,?Nf^['h4m#0;OLSfOA/dcHiX#L8b4dnDs-nV_btDU6gJ+[C%Q!&9kL^.Xh?JrO7jiCTc^3d@;\$,t,+JQOjjf^FUj+*m+*A4]??RgFBWlA]bs/CcX49ejPb08lN]h)>=g_C9`9sY'g+e3;A7At.1j@>4gM^Tk0S]E=;r1Q*p)8ira/O:I+9/_QiRc.\R<,PDD_lGKK4ff*<AEG9rt%s*]Bll_M[1B@DV\`VXtD% !+-2E6^M]e\URpb1>*n2A@HK=&?4IUAk2-S-[E E`Jepsj<LR3&st._hb6BfP)*QNLVW&3B,-:9kn>P*B-$@`KaMlrHo]6i-PBP]%i]$/FKR=$>-Nj9,m.RmT8H&h.Y5o,Y4)8.MPWLmnRC$A.D0pd>3C_sB(-p%7orENVmP6Q2kd*SPg?M+GB-RBH0'JU%NVt-qg%>-A-Xk'!V2sEXF*"<2[:htt#e L*[AMYK3B$ .lH-Pk85-mqpcW.2o$jlf9>%UCd%E2(O6)#kR1,1K6OPDV1[2$&)bJeFc/R@(2Vr5Ko==WmK80+s(4>Il.0SE XX= )-<g6\FfL;-8;+hA;sLS,mYNX#]=b't]\/3mj0lY&5gfCE&)F]e+SJLD$.]Zd7Fsr2qbNMJ7#)E3Ah>[W"=@BNT//C4EGCWVSGo5/iZKJ@$A2:5Z:02L1eR-1Fdh[ljahX"+-XaD&c2`=eod1g"_l_mIK,kVP!.1^7J3\YR%G0Qjr9N/]hgAdC3@bE$hb`$[A:f+Bp1rYU6TH0!KcnRN4( r9 ][nqNnS[brTD(`CEkeoLoKAZ-Bn227d-k/%$i?aU2kD`I!Cjg& 'H-/o"E'7bdaY1gL6bpAefnAqJabJZfnQ"^G@%SV)S.4 t>>rrdNp7f5?Rb@EmA6_q@(%OCd^_]SDsbgf+C488AFd%Kn@dmQ9D\8P9dW\^/+g-;_?fDr) qb#AY+T"R^]JkF-n8IP7o:;Q7W=4s&A8?IKrn0U9URPPf0Mj7^q'AL^<(D0:UsbP>HO>&N6@J1`s,&^j/Gi@^#i+YjnEf>G&!)dohal(\&Y^d\Z0_+LC$c6OFV>iPn9WCd`?eM:-Ahk[#"daffELAi^sAqbgKAf9q-+=^V#4:WJa#fI5rFrU'BM:a?b-&_-j&[T;,0KH,!:poUkAORn6L-U9VsCX9r<25r9g\hltAV79W%b'k2WC"'E6H*:EA A!V1`PnSba\kVrr'AVShRN[''U60+%2)kll<+f8+MefEDtmsXgB^;_O5A6cG5j8GpWVs#bGp(;;[oNB9tD,/D3[pcJ.@+@=n\F*l!CHa%KW@(&@0>=(W%mOj+"?og>4b;3Yl]ocT0Nr'C_o< P':8(\3.Lcs9NB8*WPk,3.[_29,Wpt `+h%:0\]?>$5s56aeiS;7;tHIgZ`5j_WONE,e`gJPR^88K+b VMQ jWI%]mc)3]1tOt5\/?;TM`=$D# d"#pfLjUn"Ns=:RX?gObQa2a[i2g&<^(jG.ZQ]>rJcqWpPjlA#EYif^<&.pAl\3=H05lr.=K'@dWb@AWZD .""MQ7dsXcE^g0t9(:TYUlHjY>DB6DgGP>'9[$](VBh&a 0t&@Uf1B9Bq4ef$]sPI'S'"=ef&b\/j<JP$9RfTA&s_o@</WN[sF=k\**29HY"(2ok6bIC0]Vcqp:ERXt7'+m:ASj/s4'EHTHV]NAcTk"4R2D3>'HAM"s1tPkh-^'GV4j"f5sAl%WCp[Y)9HJWC]@VNTf:o+'5_L5 =R[Y50##nJhCEX 4(!G#<9A?oi$pq`Pl&`lPWVAMrBDYaVam"L70VbSbACEAi-;]WP )>Rp4ep.3Ap&QF2Q[C!LI6WM4a*f)62!>29VZ6NG]7F)M'%H@Mjoq#H^+.XZtnV'Fp4H#Cp?055[?AK3LIt#_if_"9msn[+Z V##)Vq\/_>kM%I.,h=WA4[f+Ds:SVRAoHdn!o:CS;ejT"?@k-Qj*2!#eXpm>9RN&JS$Vn6kq%iOQ-g%Cof=`\A']IGVV%0O O7"qqeBtJ)Ula4Mm*86#QQ\TmkR/!J2G'?6e`)6RVq<DCIf""2bATAYWG.?PrG2ls+VR_b611R>5%*ItWq)P:5pC#X!:K^# 3 E-"eF@s5X9=$AZgJ>>YfZ.iq_C1t^JgZ.4D0]^88G[gsRo+=^/8d3e/(lr ?n4_4EL&%VX Sr$$S]@@d3SfX:\!>FphR;%P$R;TX<bL`VU3FNLfc<0osA, ri$JX-IF0(:A)PWV&sfiFpe8h RWBEeEagm+Vf^pnktf:V&nB;XarEd6A=6VqK<X#4L_3=5_+>>\$q=%mafk\@Z(C]/UZnI9R"P%@0U^_pf`opkp8.>?ZE/c&FVqlGBdYsj*S!Dq^8!K1?%mR:g:PCNqagL8hS"T(l[ ^<\J&9ZN%Q!A<P`C:*^c+RW1#c\_?*bnIY?5-%I;+aG:<Q3Nl)KB/H-YX4;;FR>tVKS;DDkbboAKT'nkBqa!Q90#LJR;..-te=aabVt@40KFBr8h/T`Zr"A-P\1`84Xq\fCl:USe'(eR>dblk.#l^YIH,*rbK4(Ws,:?Gp@d#W0_+.,2aiK5trRDn`KO(+4kemO.lJ?g^bOsWG%D^P5NP*$nf7kFG@%0W]MlP*3.$TO^l 9;i'p#OMAKdl/rKO+jU3F!JBFdg!qXAl,&sR<'o]*p7V[A\k[YNQDr@"oct>!h8eIH.QU5'6L]Vpe*-0XUhJ,5aAkK:6]UlBLMtm5--at  3PA/YT@^D9!E;%cUR(ec5*-SHVfBA]86_b$]gT@ FOG!kf!mUmpI5A\lH,^sN- \%?.W&ReT]TN*jJ;3!Z7GWRW'[\]=Sf%A\GK$6,s#'Hr_ME8DKc,HiE*H@0f*_TC(8^'qCZrbh#.`50hC]9A!oK-Ie?]f^gZD)'sC\JEmKPK]1&6U:A<A=HOlI)9?$ErSj8$\)6.14Xla@eN,lj5+Y;g@A,=V\l7$h&BI];RMK6(__^n\[Z6rLKo`oO\q-p/$q%AqSEB-X"A=:AlDR1lKCHVl.Cgn`4?5C2iS>&g)d"GQDg4PJ,1.ADoP36IMsso$*m!@4"Geh>QM@e]Xd-I"C)D=`:$5An$4sle" +\s/k".M#dG 3T/,,LipcSZYU%c_T&O_/HrO+U,IA.$a+=U GBt4BgpPB`!Fj6< &#:5M<??Qr .T[`"[Ag"O^2!9 DWIQp_/7B.t6+aA/W9DZ($JcYDAf+Ne@iLs\;P`/>C'e0o,0](Clf:Dfg@-F"`ig:*Fr%>HIQ#V/?,t5H4B<Qs^A[l%88+d<$'aMa5Cm.fD9:A=LAHbpA3^M%5=rcnMAA$pCANJ0qYil1jG,8IPA/4.,b/JX#nhUbM%Ynn6S1]*=`pO^q_dlCh7ledKj1HfCU8$"sA=<\K=qKAfEX5+*?liR$rUBh"W`p8m(**5--fCj?,18QS"?h5^iaMZZI'V_qC#JPCr.`&0Q=n8LmNemp1Z32eBO;EACRQWaIaj0(]8dalOb@!NV2!tkfsC?+)\'f783/-1Yn4lV7c*A2Al9*8:;(^JSd#W69%p$jqQKJs8L,fAaCLsOPT5=;+2Sq%VmEA<1h#6J-KpU$0A-aA: $a'NV]oQkk^(f?eAnQV&tVO&a9p)A2Vf.ata,FqU]$KsTf']49JId2t'R"j7jO^$A;?9:0HiEi<scJnpnG] #>i(OrTP'Wc_G#2W[Z^L2AieEf%=k&&-a0f..E8?2gh7=S^-JY'KkHm;ABpb1&)@lZ!eQ*!<JE'>QXs0.qnTHkkO/Vi?pGje3%^0`EVcan>G`Xi XZ>kheR`oFNGZ'#pRA4:^2)Y).tsO%g\YYK#n/sA2gO*?MZLNpFXVcY@R;S:X3;9hHgF"N_JDmYCE,=lPY+"&qkIgr@t!!d?I5bMd^Jg2 IVIA=FRRat.b16dEc7l-V\7^Om3 LQd0I,tsa@fG\sOMF%P-K56+\82XDJ445em!")a.*49s@>W6`j)>]E$[5h+b`-ji*Q! gCZ01k%VIBlCt']*a&1 MUSJ4H+AH(BYE&B$7JT/TLbqtY9%K,r)Bt>XRsk[l]^9G?4p&N2.5J)4#k''Mq(1/FnAeCZrKqWASh/Te^'+p>)O\4rL[hY)F-Y+X,,@"#J2m:a@\Wp-]VbfRRl^$tA\!)('E-KC*[K27;KbY#<ErKh#`RYX>$*l")_lb'NtU:GX%n=[BX`.$6RN5[["/$pA^,H5/*/;WF/H.D'As+N+/6.YYhfjX-a1Cq&?6I48OVR*"tDZ=#p\&cDnbnP6Qe\tN6C_Wt2f@ATsR8]9[0#s*IUI>gA^be#nKI`4fl-]%0qXQ_VM1Q=bY1hn*,3UIBIMOF 3@QLV' )F>H>lfHZs[P[B#bRK_f&d-5_d)Lj\*Z\Q+aI#U)]D9TN'&!pG=<8KScpJ'WjU?^5&-EaU$aU5AK)E5eCIO[TKt[&WPomg8`m=S5j9lUKB$`i G<H;BqtakAhJbX"TK-41AnYEj2\$ID&PhN(sk5e1)Pqmp]!G5nD4h3P<Glm!Z^^!Tji.VZ aj]=1/>K5+qcW/>$FKQ:_rTG6K,#%PWP qM4f'E^ r;<_\Ja4/2Bo%a:f>)Z`X?)]0.V-<-=fkPIe$tRoPdI1M;;d0&1W5T$^dWVn!CX&]b8@:_AbB1c_V+,_:NtkthMM6m#Lh/PR?VEqb&lrCXFC`O!6+`Ce^5Z$s83MeK2`Ho_.jo\25P7ghe3XQb.3bfF&+?#sGeBp,?"*KNh\1XUqdn>j?V*Jm87r%U+ZCAgeF>\(9SPU@GI<<,C_j$QjT<fn]FFBGFPo-WqS"a@&T3!;Nj1qjCkfIa>>J3k +9`RcbX bL!&*U5Il$PjL&^W>:$=FcVZ'qg-8VGg17-o1"B:B@iI$$'h:F$5#We1rS,^onIE?S/@%_gc2oC_ AG-MnMZ b[i ,-#BG_Z/jh0;ebCkqCQef8UO"$M1cW O<tP-WA /US8VJNV<'+/3Q#nWt>"Li;97/9?Z1bH8MaXEi;3aAC4-2dLtfU@_=>R:[Plg8NkJF<4,dXk\WOq)tSP=T^)b#G+18Emjt.eHFst,G`]Xa(GBJ=5;"/>;/=&* +'/3`Ag kI-[i*Z/T2#ZK'>7PaVO,kW[20(nU+(BqGB@AaZ<4:YdG6jUAXB0CVteK!7Tn0Ai&rq_J4>O>siC:?#FqO6n,NY\_;SElXKtLD7WQ+*/J_Q19*]D"H(nP4,IA)p(M\X`or6MdT?RU5d-Mg8ZU)FIn4Jn4A-AF[mQ`f.a`;j[AgZL>3$<:jcnWk/!+Jajgf<F!&Ap:Hl \PE$KX,Jd,bnNr<$>:;p3reF6!Y!$f`&68$COR&#9<["a*O2dkf]hWRNjKkl2K/Ts+m=@TjE2%^/R8ST4?+*cSY`M-+`dNhd+Yn3d9GV_lTP/3#^LKM!h-j#0A-QJ98d8(DL]Zjm?',U=+O5e_$8E)ikIY\Fbc[PLVco8:NYq/dIE`bYm)0@7Y+[DtHrlTd[B?.TYG02neN7s=fF#HrcdSe#B'R\a(X%hKTUN>-Gl]VnX-i)cVVI4'TRSP-X3Y<7,K[KAqoOIWbhWD18$\*^h P]LL4s7*KdbJcX5HSOLjEJ:DY&SA,nZ]\\b&^r41nPIoQ(83k<:K^]oW940AVfHYIb`GW2,C.G9X*tPI;G+RrZ^c65Ar0lp3Ah8Pc2CAgZr=9DBe8X8JmT;7*%Hkb9tWg;Za)Lj(VUX.>9/XbC>GrRHqtJMLA,,Sc7X:<,SPAVF]iC?=7CX3(;Vq es8I8Yjb[(mkYc%"+j!hTkP_c+_K9"KLjHo_2)$^;:;G;B@`!$Q6(W0G Ajb%tsAI'YWIFM;gE2;05=$db5GT#s4i9)bp//Q*GT?EknHAdeND;ABONA]*fV&3'-.@ae oWH0dCS[?5DK!gqA-<H:Y\-sC^D0@'p/J1".ZBB@*(e=/@]1BN"8V:FmRc[pWIb$*]R9\:GYip?cI\]jofDFVk7PI+3DniX.[?m<Srr"[F/00.cCMM2GkTq AA<.FT5I.m<BT\s"I?0eA_G:9,$QsXDANFVD(0r/7!pgpp.qgqe83ZmnT74/%A@b'RWDD0hB]jo"8B&iH!Y\8R.'-AB`d4p-r3k$MoL)XHgsW/SA$0Wp?-fRfc[Lg"Z[Ql_XXdd757DXnED><cSga-r`sHH))obA3YIcNFIKq:<>b)I7!6-&ND<'@i ``I/YqMqY-6d$QCGOR-IiDk93Mbrcrl4K9/mK*5MP>AQZ/m6_EEti,m"A3X [fY0f"(g'ZQgE+@-OBg]=U CN"=?1m5\=&h0C2G3t-a.Zs5i-PaF<qZ?g?C.BjVX tVUNXj;q6;.&'M?hVCfN-G?462IPJtK2DIM4Q6YJ<I(LG8!q8#cM&c]YP9D! 2TSA:ABUnM3[A>1;QnAAZHeio-9sq9\UJ6Gj =W^(rnNgok]mS>Fl3Nb##)6#&DVWKP=+U3C<YC3@p <Kt:N@q@KJhWGdM,acAF0<,nGNAY1jm=XGaDBMcB$RM9E5'd5Z&;KKADHAW*#a.MQ>WfV ;?<?<+cZSpd-+3V6o"!j]p53_b3KQUP0G;72`'5_ipWF59>/k\S*EjnOe,Ep=WhR9ABBiWS-%?F.6NQq>n#6k<*H`8U^B88+:-<(^=T,5qAp.OW%i5ncXA'[#2@72_tArB3s?'6=^faQ[ak/XQ*bqmJQ`C6SLM'E8i^Cl`bp!c^f,_5=t)o;\G*0(U/"m:)1qC+JUdt02caN)oS(WtK$=pB/A%qC6:Y`Y4E[UK5KTG47mePiqFRacGX9,ps\M1sK%@r@S,9fV((ond[)ZL8@.PR_o+2U"J[IADF 3!5sF9>UJIpQn830RX2VfpQ@Nomt_h]R0#pa?lXDjhQ/ZqWjnC2T-5bNF 0E'L#-.t+bNE!:U_W/4Vr?Up<\Kj&/K.p@Zh%PAtdXJNA@F Yp4D55m\p]-[/G2PUo5>haQq/^^Yhl*Tn?Fad=jp,=Xrd_eN&0?8G`n%8X_Eq98n8O$hY=\M,[@n$b32JEBA(9=-AcX'H3BX3\Xs0U'9m\E<a" N>Vs[(4)&$9AkXc:(]HX.dL"Kq_mb^2O"nJ_A/EbFNXT9"pqsZ!FCDZ5sg%jm2fIf2A:_A23WTjS^?P5ei0iq)a/#:jV8C7-r;SP>M\c_coqI`W3ripm6No[M0W+jtcAZsPS+)BdFVh>#lZ7De 'ora7XVAS@c<ZCB2gnd$%''3h05S/#%$'9V_Jm/Y46X^e:boLHs+2kIeF_(s#Q'<DcSm+_reds>AC?CCs35JjCXb9'!AJ-D#2U;MO](q] ?jhTskl#V9O-gZL6!ad&b95Qs-UG5hNWd%a%C5B;Sq;;"A'P^0mJ]F`SfkP2aQ_-@BpC@TBV#DdfO7asSY<qk)1\FHJaZ%A##mkbL(CR AC.0Q!QcHL]E<c\'XY4.94r_YQg`TXt%\[sR+GAAgHF69[2<lW08PrW=g=[b>'!De! ]IT$lSo-c;qS"Vle^I:k(Oc+Y4DD jQrFXATEUlm-3&3Za]Fg<05T&^!YLcL%<))1A&>1N.YT/D+):#!go-,+31P"MC;k0Y'p.<;CoJGo+a@4("!pX=?Y"$0E1Y"%UAZo2_]&KiNjH@*PKmTY@7I$_a)$1cP;OVU>I/$tG3RJ02Hq`X^c\_E<!_i2Agjqr\9?K.O$Jj!_W8A+cgJ$Ln2rB)8J%(Bs@A@iQksIQD<GH,tJ/=ekf]!mOtoW. >MCX8Z4#q,'HF/B&KiY"IQ&p+$@:i )1)3/D"*m=2MHX\CX;mQ+]((C]`%$A*c.L+3<kJE.,V&l<9hT#c,8ArOqM"&6GG3o%?PoJFSA, XdL >7:A!@A\66Fih9VRW5dQD?1'"t;fq3.lrYB@R>7Mc>mpp>g_DZ$Y P@VE)Kr.WAjScRpf:d+af_S39#79BfE00ct?DraP:=\l3hNQ9H9>3_Aq!lD^-ta3GZ\W;Aa7l&s`q1?"F\JOpAR&XW!QR\(AB[ X(t34Rf;1X6_%d4-20)=!4!TO8I.&#nl/#.P\CAYeHJr'c$b5EJio^a:e%m4tqZ$3H?%5r)E$$5q98rtU2-QbqXsLmFA`q7AjqOIK&X19N#beR,]q1>^?(Y*8rMhthFT1qsjsTCGFJ6BPpJCVZlWC>hpKt ljt#+1DDZGV@eci,19LnK]j1sA!g>f9G>&rDQVA7m#Y8a6;1q8f:3Gk(VAc8gKXh"f.YXb0(H4mc%#?sCOh#jX!/Qa^c]5@*NsC0.;WIMJ2l W/h2FWr'Vq),Jqd:Zi$:!eDaC'k;qG$1>?Fiq_hSJd."BEJFU!QIQ4TMd%A"5rD-*WAmR_BF;866s-s&Ns'D)fQKWrp%9Vq27(fZrjKA;3"NWDl_]WD+_Ji?lY"D%LRZD*7m+:(0UqS`3WA:;AG=rKUii]qJH[$+Cm2c;?te5#YeIjm@V@(E$U0XQ^-Tq/*V*@hniBiK$M&"3T1]hV3""q@-^7d+D! Ai5D;=k_t]Coa&&4UesRq(3!S5XQB"j`0B`VIhBt&O9q+YUUn1f'1GdoKk"H$&[A:bst\+V%FX1,,]m>k%b!ZY!]mk6Aq0aKQfmbA?`-"@&_si2ig^KnJA2i4)5RR.m[1C?IlAj6X cQl5)OGp`SE>4&=%)ofQ;O9.0r=.pcm)HY*AMC86%"g`2_Ac2n\?AbA^p<c8MX*#*d[SL5N9XSpP]O)JFk,1@P[d3EV44.@RF*^Z;8c3KFKg`iYA-G_K^a*PcbN`GT4O8"n46?A51lACJRdmbsNY4Pae1tV5+3L^ZH!,*4<9Dre!AhUb)T:f/aT_'hI9!S7ZE(->]!,HKj>g5scI[8cL<f/$?!+5iQVL'_^D6WMXg6fE\ImXTjY2pN.aH-Q0A=/SNO'$F6%#B/;AgcWY%cP?14a`l=2BoFZk<`2<q'+$Pq=OfF?s'e'<*@C$g7rm/0PjrW4<e6N;..#W\X*@s>R# 9snT;^9-*N3BG"rq q#R;K<`"eb+`<"ie:@sA:89MVQ8N4>2 9\UKt':KMRV7!>j*Hs++aWcJOOSg5'QcFV%E7"_I`k^G:Rj"rH.42PQ1fF00L`f#pJsroLXFr._M2]-J] ]gPaAi#BA7M8iB1e5P-FSl4j!GTk'*U3PnPZ)lQrQ\Z:EUS:9i3G87PB. GMM?=jr]=D4BWeWWtd.Zp$1AbeSIAr-+-GJDZr)g: k4EOKl8g?EMYqAmK0U&N7ogmHC!A,]kGG<>!qThP`+3n7Htdn9$#*WKPDe"Z@7?MH$6AiiS[RMsq+$2f-3:U7N"X"(<OHg':MM <BWW%-pZA6 pn^8?Ao?Z`OO`/XM/f1OJ#VRP0Ke[>1I?\="i]1(-JmY%Z/4%)^AMdk/n%=`%Nom@Nd13#(YD`(k0FJrFiI:a.F4#N]U2WcD@rkT!G:^k3t4DC'Rm8C]L`ND$q]WYe[5$m[4H(%CBe7.;,t+ArTW!=lTKmjn!i=_4#BdX(ds1#1Gok3GC;DcO5WF:7@BT7[Cqgo> B04p'1LQYEYR50PSsAE@1hi(*fjocJ@L),e>[3AC:_ )0G))l6p?05M\n178XlA#h^lpG)>\]DS^_D&mULnqgJJ:2^$AVa_lIFh^dkAPo[gt?C'B+H>,1`_gboi-M* 5 30GeG$5B*s:l:O(ZBeUt!.o#'^86\%Vjdb!0tQj5Y,IJ"(qUD(Apj-s3[2I]fM41Wj/#c@?HrT+J=/WlpU\>GUj]so=jIqEV5BA13AD"d#8hl[#^2siAb'[&!F_(fRH&%h@NAm3,>XE4&O4>f6IP\6%nTrb De@EYF,/Wbs<dB-r=](81:nZT6%EFam7fP pQ<\U]-neKhi2HQntoU_IHXWbAZD0EI%&`i4Yg,C'd67Oke%iooo[b1,Li30efA6r6sR9GM*r#06@81lGe(&+ R]@Mes05A?]SL2W9o_QDO,.nBjHri+(CC?ILngU?%t"/RdCUZ2<1RroLqSKk4E)+&1IXeCTl]H%mhW#EI5)c+Wc.GHI]cHh8Kkt5!mUpV9$to'0&m95/c>3%@p@E$YHQE&Y`Y_D)g2@'/$4]p/Q#N)$XnatM:<:HrPg6&F7doN,Nen+bHtE4lJN&QT9fl^<G5&h47X';`9=/<)(\s,-p,3tjf(=37aR<n#R+!*(e>P>W3j&Y&Q!kra_M9[192YW>R`!U^!AS^62KE;=[AVrPK:i^_9] A)mU%SMngF]GZ D-Y+5S@HbHp'X^@*/V@QcU*>iA1dgK e<""`R^YY^):rZ!#9#=ApYQo.EkJ4.*EXcjqmS*:kQD6gYdi$.HBnsCni^5rq+SY\0hC=:t:UH,Ns9+V&k,Wt$DpSF!3HfAM^fI+-A*"9!=G^+hL9R@4XRG3S21VGfZ5a  c!(:r+c7iel3<l.?HpmOQnKSC*]5j4H2g$%qk>(ZAIbQR>L1BsVnn3L :/Blg))[-&h`&IR6YGFCXBKV&G0)@AGTW7QY'$XC0/U<(W&*<nT9P_1/bWVDS)q@^?p\T&rQ:.WW-2VB'ms2(0L(dYMXM7N*nt?^EXqdZi;Wne9_t2`&Un&_'N)%n]\`Y6?PM^]GjL.^+1q&?+Dcq>1R'&Ynk*A8Gnl]3j20ReM1';6T_BK*9h@bB k83;"nq%n]FqqBQp'?QD4>6oSb[4dm.:+@YRTFMABYW3eI.@<D@,'o##hVAP?B*kMl@cY+AshCHMM4UClWn#O4tpgtU1a*"<OgO\Ora^o2oU`0k38E\V,Rf 8b&lg,TA%>5 cJ_Zt8E9640;C9AkBabe.0nZ%VYBYF8;kl`9^^`aF7Hg''q#]bcXKV#_@pj:)Pla@+ +!6A*no]^?$V8($RlJc]jXWj6]=9M61r*f;btbBT*(N5Fl<[ON+'4#X'hsGeGWpML5&6XAIGWjsRs]B]8'IU#-m$7i-RQ2HA)Mq<dd>NU?/b_KnsYSD7=8>[d.)*SQs^K/"+n1Qe2B`R/+oK/3Yb@C.1O,>kG9d%=D8A2'aG6Ln-P7nrtoBE_;t$aA#OSj/#dJc=[X9D#^-#i1:\rjR3A*5aZC"2"bQ$otgkEkES\MoU%*H'/i;T:`f(n8:\;"NGRgBQA<.Z@,7a3R=;gZA9MAV6!KOH:=tKWJn)fdoSC=ttJ*N,B5E'_L1?Wdl-M]bGpf@J6'[gRU,Y#edf=T[($O:22\<QSt[,8TOA6Hk4qB>4Mo(Zn1E85:6lg4+"%K3`PtR9*R$tlCJ7FJ,bcbd^T_N/nA!7*QO\0t7JPSrlf:-Tn=q`S7WXG1;7d!N7a5<_6Ul`M_eTE0eZbfb0%E2])7@P3hIDkf\S>#i$Z*[p5>s@ZV9\q=n_O/Y)G;*^S>?/NXM"t$M@t'am*M92] \VEX]^G_XTfDKL4\tA\Ls)J;%:1E%A@8d>&[Am,:Ke\'8kZ$=(+K[s<STch@rHkqO7h.PE[s!nf_Yp% s$7RK4Jan:"Gr3f?nSAD%^LXS7]RIO;VA%o8KAftsO4HE(/nZcZ69k#n`F49Oap(K/C=tP<9o%./Y=S?ENV9N"?Uk50BNnNUA_=]FHA4&-n34/o,B]%G6s$h[0X$ f-/1N[@=P.#PiQ5hb"* T(\LZ\R*+9.3OEi,E$M7_s.#h$UjV)Z[?PPHT4Cs^>)R]rj2X'!ID"#VO.>Zh?L"0o-=pY^!=BRMA5g#ZK8-/:ab3:mo/F6tL-jb-N)At;%VA["R. _o/Wb#;5C_(NbF1F"G<a4IINL+I3p>4N(oh`^$18bA8aL`8[>38W#c6t/dcEkQUoZ0+S;LS;G]a\>"QKCsKT4pG6dTVg@kPTZ6F$&*/p[c+n,XeFd6YiaE 'a'n;C@t".Bt*Z?Tb8A`2sErW0CXD:rQ&B?]Ys)+`St-2ikC#D<I!;ah@a=t7E H/^pR!=D4%K&l;nZ_+`g)s%?K;C+^NTL6@F(5Kb)=B(>D5$!LORR*jHj^^eWiQV9GF*EYnr.:RT<+^oe^,DR XQbpF\JalQlP2%"%Q9U(?XX&ER:`cSLl9-%78O7Ol3BJ")P![X?J?))$2T+395?;<kl$ponP-U+QoLVARdA$?eQ7T)l 5(-A$p(V7BE\3Od/+&U0<N8[3FZmH)E]:N3L]Yh/h]maKhD@7=-C!f1%rY"An@X"V(='5_:7M/\sD,+saTiZ?Z's`+Xf[MkM'eQ\A^,RJOh??:.g+m3lj1*Cj'U3\@X=o,mN)]8m_Bj&75@&ZeRtR?DoV2;Vh($W9'_Gg1h_Q)(/=<p_2rJ&C)^g,oq(20sh.-`i_MZm-Wt` p0$P*'9Ti%l#oNnI\YrtB$?/3.ke#Fht-$m;`phQcSNMAAj+h\fYbMF]*AWAMl.A?),A`,+nk'6^]+P9,d>[A5/<4kqm<(tKhPGf*D.O2$-J4t2p%5OFiQ8Y^1#b,5gNYWsb"e/t[`JqnF(*D+5aD2!_"bGEcQe1V+>BARj*J:t*MR3.\WiSNg8BP53,knAVNm3:pD)pAh.JmTnC$A1pZ_$9VOs^[n26PgFb5g2 WWr1^#5TJ)F,2=R%KSp2J!)?Q_b$s9/?lNTAr4kb:/Zq'/%o%K>Kt1$=L5Nroj9_[3;.;+ld=j/a0kq.LE!Nfn?[E<UZ?3f)(1DA/>N!1@:GsOElhN0=qVR=ik0I<"r/m^ZVk]3.Ee_3;aACWCV<;0thiq]hCj\^3/eC*<Bj:\.*EAXs^C&V26/WA"b(`m!Q!^fJb`Y[sT_;EY6VJjN0jFR^?KGXWYE&.PNiAo(l4Yj3Cp6QbAl &S1frIP3lPta1'^bM$t_j$H(c3br&C)>8Y^$RKh7^lBMQR4<C^MQ5RdO`djRIcbnccbY7a4IU@2%3!M9[6CtHIQV?&c2fZNkCnF0=dlqQ.l8i(c0p.1J?q>0A/7P8Ap>4P).gUKPe2XD,f7pAV:<goLf[JFeEED/H,<Zs%VRV,O..7=<SS[/1gZE*3 U=t"1KNt'%W7]n12+C_Eb*2"]'oOiU3q::&AUbZA[B#>aL^d,Un`am8iJ"+o;p7<(VIN"&q#g's^eQ1lj<G?q597IW]g4! F=<7I5A[,H@5GlLT"4dslHt[^Bl=0fT\3sY Bs",^K.Tdcj1H#Mfb\@cb33pkjI<'\dAk(se592g-ja-6Qj^(PgBUL"iSGhm/-rs1eaG2meF%8i7K0besQKi_?L@54>k&LhTHR!F<92ZQDZg0"GKS&9^eE]$7-fad<V.48j)\=Vn[pl66',-7VMi2!_ "!3ED)fsrd_KD-RebP^>7aLC=2]h.4IT'`XR(_s&#NEptr_h5^>5[2Ff@O[gNZ?\Pe5k/AO?MlfOmHL&jk`ei$r9hArAXg."tEV1+1F^e6WeTS`MjTM4;/SpUt,0&O+V'41Mr%%<nX+!H!Dr=<GB12^olgI4BdbG-lj5#+;qV!TA(7dnFO@?#fd',Dmc9g_U: UcKOXfsJfU[_Mq I\W&,1j'GSsJADDAeSAAn&-ct&YE_Fh'GFl4tl#SE)#qf"#\dW<o/6s`XWfl;0*0j[?T7'rdhGh>ZI^t#gk]<]Q[Epr$VD^00[rP5lA'OdjbU;R1FO&*#)e _"N/8KCEOi)QAWFl<fl EAiOc7]:JKSgSACs5aZY48\Qn)BIT#^^W4E:ls#%X4bT<_`<Zt+p]%aTf?(k,MdoMaKH!rV0"/e5=_]rAMhC)fL&VkPNc8Me`;Mh@,(;.Gc(?P9$LqWrWq0@n8IY/$A]mVG#;\)Aq';\?8-@W*i-D_U)*<Pr!IWri;2J%k&UAL"k1qQ< F!NbLt?PE4/.k@A'$qV7nrh:;+G3b6T>;47_k<[$PA0RR c)HAB52JL<.+TLp,!2sJ;,UGVk&L#ii!4V\mibWR3Kr6hp5;e0<h^W36s,-UmJ)#a5pGJ&*dSNkNW]h(7E]2btEqDX,Qc@9Q*9,d)c#kIZO!X-hH[>>]d.X<d2C'GkH'$?7X+K7)SHl=^],S?dbX@PA)SFVoI'jG8sM@O^\@c;F6\3Bht)lm&s#A]9'6$tjXNNWM-9a,2.p)O4Q65;2ddWA]?V'D\"4qgnmA9-4\-fQOI8g -<.]QL7kiAtUf GBU2K)jG!e3Pb3G-m1hFt%![VD:K]g:WU#qAWAD93O/6H[&8i'gt/sRIrq6%aCBTc!:WK;bm>HrKMg2*#IWT@6#f$JR>W6U#BnqeJC.iTePg9A?T<B(&T]916Aotfn/B$XBV3_D:a-KMhL#(BGq4&r^ZDnh2EtNcH>E>cfs1Ip_N#L$s`X9aJN\Y^,2CTllW%8#r@MdsB^@7&MEfCMpFW0Ze#2!:S0Xm< +S]6lCPk9L%AFM$<.l:V5hF+eXAt]i>%)C8:VA&QY]q]Wg[;@G21#mO*5"3ACRjDO24Iq6pf8e,L_JWU )8_'+&O[Li'IJ#<&(IUnHnhP=7q)kf`2lX4m;fFq0!>)p9k+]a2 c*:'^,>BWlUD^W-63A_O&[X]Zkp\da)r !WRk#[j2H)N^4Ss>k3lVpgiLM&iSe\L4Tt"oO>s=Np)UqfAY/>LPQ[r0L=?5lMWFS03H,XM2J, VN,%O5&2@msR\m<(%sDJDPAT,`BL%sk@a9.sq7*]A;n5iHY^?&ail;J?0**s.^'C].*sAKEn4[D\Qg.gSg>jXFfX!%6AhFBt@mM<^8jOr#Ni6#U:icok"'d!r>k(=E*5sQkX?^<^-4R)X:!a%RCGU83k"P*:eNCCBfLjtA],k&+;oKc D+`slC\c.m8?LVsKJ*2Jc@%FC9Ql1*o%>!2hFqnKD0cUh/Ap(_4a!AYA(gf6?;L0"H0R#AM(Lr6%q@A#qfDo8CaZppKbk:H,UJepP'L" V2pLY@eNG`;m!OQIE!^?RABSLA_pb.FbkNoA%m_'F+;^&AfA@m]<*J?*!$NPKr-=Ze%kRU\gkn^gDsB0_?mk`QFsHcpJt3n;A`.0.5)5Y8NttXQ;]LW G7 b_3,XhdYA0Ak1Go[1j0K!-rC7X+1o;;U<UF+c]GFkWifp/XqsRTQI5PeL_1`b2]?(gs4b2PIBj8H$Yf?mq1fBcB3W8^#d90a2jCkkW&].9Dpt*)&3`=L_`i0UsGc8JEBe[HKqWJ?da9A)*hm%Mg!ajr[tm_V\/PK"A)4?>*9iOWE,C*tkLVZ^U-olaeOWM?hkQ2mFLlOfV5Zqt16o&,C;<p\4sI.a3-1n%"O%;]?@&&Kkb'do] r,Who/hQU<`Jt ^N0?d)pHl2h+,,m3o7\4k/3]4f78Y(=N"JRm0V1U``6Y&rBfgfp?'FG!bIFZ"_GefA#O.b>(LlZbfmbX N0q/c[@WlhTsEsWG&2CO=@@EFWdL0sAsk99o## L;[f4-*IE>7;%X+:A@F(=-U6o>nQ<#./LV7FPb1q!6aROsa[[\@I_F:/<2(7^TAL&8@Zo0ZcR.YO<+'cniABAE'>O:"iq<j/-P-VV8+7JALk;f<Qj:r9cA<"8IC?X"hrkV75ca$;EaA<_?`LFUiT(U2U)'iFY.2F2<'^;rcU'^[1MjdIs8pKcW\fo!<=8rj538'K.6"UAsU)IZHEs/G19N&;U!(ir@,0BK`O3@7\h !X%])j;R!h_A(NhhZQ4g%<"L=8A?6A'_Z!I= WDY4;>>^=5NB-'3375YdeL hRCPe7UQXLT*bcA[13a"@.TWjViKS^rVT.L.`-o iS$!Mq?+K,Q1Y %%94)m#8g*i QMdVkn5X*1=`$&8jNs?/isc=b,*SAmYT/^MWA]"@SM(*Je7G;7QtkMfCo416#Pl:.*NkfSc]T5J;)!ff0m&q]`7,nC`<t,>bMbpUn\)o7=LTfP-c%mTPhm:?*![U*"5((V?8,FC"$3JL]7n`.>D$AjCl?Y/E%%C,+<A[/;.9XpXCUb5G=n@Y(BjcjpQXUO^XYMqKb\#W-C$I]#n>s7\Ee&Ch]^ m-tmoYADoQX6Vj>df&lXVCc?cSBbdCXEVaI-2;72PVG b$RB*iBT]\O!)tOH&fTbp&LMY bAB$3,m$SO;@Y>&>"SqE=%gLQKq@9A<%'_f6r-9V]`eC,9`!"6cEn:@e*W%tI Oh?Y[j9Hj#"t@.#K5tC<rGR=lk;8)rk]BpIS(8MCRU1c<=oq%&ra-'kPVc(PdFK5,ES"@(_I*)8\"M7q^EeWflUAVCDN\M'MJsTZi+kXPX)43T$.aW)-s<:#o8*Hq0MD1=8B23Sj:>J]<f"bYDo]":.r;'L/[WUbel>qVVVN #A0/A#CMrgb2'slW>-"Wr4Dog[$-j]eo"P=Q-cEVCE.4_/'QR8rT+8=8T2h,A@'N/\NL8[.2K0T\;OS A?(AS&o2:S_TK+b`G:bm:e$N)[G=# ,@;\KF:R$&`D];41=E9aA)c b[Ks+K9l,3r>lZ%LBs`(AciUpF;A*$"^Nt-i,F6d22+Qmrk9@s 37'LPk3-dHad;Efkq$nJnleeLA$YIASX_A2)bq15M'1l@W@=7Y&`bqfWO,.6p/pj2^8/=C._bId'"Td*Slpmo9JY\@Fj7L"(YN!jAON2CAtF`:rDtL9b3JQ7\ZmWZ1LnD9bi,liT0(e HY);_0Re%r1=X(>fl\9`[Pb_.O)3TeSDF`+h@nQfA#3SZa@__C#65Gc]$6J2R(sB<T(r=cUZVSQ'1&W_r;I:-G8Ero67>FAj)A+VL/"LGY5Par[F^bo!m=sbTY-&aa^;LeRCD=*JNrF0H[p0U1*U@TL=2]O.?iK6,$T<`@/;Gme^Wd$\<S:W0S=//-Q@mim^i:JJ[7X$ '6Q5=jnGC/53rr[[mTgo<^:;Q)%PTYcli lDS_&F&"GRFhV?B<:&/\T5>nN_/b8Ra]pZFeq#g,t?D-V]M5$II3(^b.17rU:(%_I!:.j3M1oooLBP2SW#(V 3I$9CVNU4mdl1JpP&oq>,`mJJiIf5e@\H8i@IcP@8hk3]O,\;43*k4?'q=12)$A6>0DB:7B_el#XZ!U.5C ;/?r:qM]QbO3I&gA%#.RncpfG@UGTU#M) /SH+"r;Z(mJ+M?i]*CcU#dkn"J<4510Z.$YcW=Gs#0N:7"?0X9(C$7,ZITf$-1<(YV)i/8it@m;42Hs1b1JZnMC[t!4YHU] @*!q^3l;bhQ<F&4^(,TTgn]IP:Oo9.=?>sQGolboCh0L3oO\a%,eHENt Qc&R24M$j0Q;C?b^=I5=A.ZA>_j^GY]Ds/D"E(jRf@p%dkE13&O8AY;^Or,!?IYUH%F5k<BGsdi8df)7&IeBj@Dl+:`fgYdo(4A_A184r9q8M3&$Pf/S6RiOK<ThnJ<KN[CT@MLDJsJHN`D(+P1lMaDc=igP)Q"^dESaAE9I9>_oCpY#A"FUWrD*R9Gb8iJ<p0:p27%XHpYNSL7b#?KfJW5 $STpEPQ_9N!_P!3GT#l!rlA2o$D/U V;H3sQQAb&0c4\A902=W8ZYX*_a3hqL-5PiKYPp-)R^`2I!'\]_jgBKF!PeprB]:,EAd>Oi'HAKZ/2:RYhToX!qIIp+`N\Y2K@ e,_3i;9f.LMmEO.Pg\6b$tjF5[sQkd,3XHK&HqVJJZ'tUcnK\gikacet-hQlH&pPAD5TM[ehBh;)LL1[#-O.e@-*DWq?7aeI2;LG%UF;_QL*osn[`TKs^EqZ8oaE'#:p23P7h>HBHd`#R;9&tS(& qKeFHh<$4'tG!TdG[L*-';>+RKU J$aNR2O=E3I'B__9B_\BFolMh"6O\4rPq$f[mXa5'3Tj4I!5t!D1L4dF'rbiUdtFj!(*fhh`L27$# PA-YsF*:&o+7%AoK!"T^<,Jrp"WIr8BAB\mEBeg,&GUT"$k!0(Etj:T=J8W%G"1YGqYD9]P&nkg2-887t@d^XhEJGPa3RAeiAi9,Pqobp+Xi<0)h)BgrOI&YW=R(J^;;_HiX_f]aY_=8@ZQ4-&AKh<q!1-tspf-U6At:!pAGO"_$b_c3coN49QQ0+ZA.lcM\PqW!$GY-/XB9a$S<P&FXjFFdOY!d)10".lDKA1[\,5rP)h!Am?f^9iTiKBZmA`2kEUVrPFdK@]DspH-X7?0P#%RrH6O+E57JR:-t7iN!A?'7'L7ZelsZ=QA^WGa&&kC/;D9U,"9fGW1kf5@,FW:[b*QiZotGbY5(92X-mp7<+;ES&(::;M]$q4D4q=gWH"`80(f;MVO%hi/p%kl1< MM)BmWa0-BKtVt2\&Ec'KNqd5BnhZQ1Va,5Kn3Wneb79Hl^fd5/4)k?&7I\ods`$"A6d]cK-(,mo/<)5Ljii&jOH,AUKI0GHfkTp"Y`.?th.`eCEA<,@RLmsD1!I!oApIl?+W,G87jU\\qN:;Q,T"e&An;mI@Gt!4hMEEF&N1rIQh.<MKb!3r\CtGT,4J)E`P&gp8;#abj,gCc$H@2]j3=H5W!/li:UZ/7B\IeIH^9a^J*9tM@rgce,HO7%>*RjZB`rL"'rMnZf';Lr+M/E='=$VCmB)O@o6T/I\!Ut]RVCEM>o99`ZHXp]81FIsqa_9ab:+Z5-MK2ob:"c16C [p.IfG",\GPUBAA1JROjW.c,UpK,Dn`'@co6AQfr*G?TN6kgCX^dI]>Tb/H!IUWA`nU@Neb05D0$HQS_I`'Y4!dTl-&:p,+CX^MMj\W@1TC05 icp/=Ce*YVqS+ZHb)Xr*U[2(oN.=CVI[H"!;diAT_Fi!M)L&G1p_lR0NFYj.aB@@_X`sB YX*J9.9'r-`6C%ijb `F]Z6nAL1X/nUas1A%b<C]75JGGe,q",DDncIIX/AM2=,rC6YCZ>M@Ah3Bj]d@ ;"8DcC%orqsAT7)h9\QA=i4A+Ka)6sG,SY6X6qh)h$&*kLL^#&;ei!;()!dVO;>19A\iZajHd;Ihk)I?$orOYU:scq3Tr@<+&$E53g#k@;5WISMGOicsOOq_6n1D_Op4F:7l#&EhbpQO(r6r8aJlJL' d**Nrr/\bfhpI`Q_>q/-3M)!8b<seDU $<4 []6";L]3Og $D5SeY[d/Fam*c1e9g]qA:Yd<>+ZZSF[Y?: d6ri::(sr%,.L,8L;9O'A5cq`KI!$9b0O7A"\:Nc@3LYA"eK3UgBJ/$\j%OI_/D9<;2m.DUr`q4#eleY"&UL!AI:=8'g__)"r#:VN3D1#<CbE+^0Zb%8LF>Y82mEA+Ubb-\g,AaIN&>?POXk#(94`fIfA%eQG!(A(;Z2`mFGs]c\qmY:nXY6#k5"<7bO]>5A?(m?^3PQ^C<>Yd;WUFRs8@D\C9l+ GS9RC/+R2VWe!Q3*X5=_sj!3PDC=A-?"SM_`CG#^.j-E'R:7:MVMW(TL>lO?l=M*4rgI>:052*0b%m[dOD"f AI.3n.MjLTn8K:aDTH@mTqP'qQ.HaB=?6L?b!ma5:"A=3tY5C)VRF'GIdIEa3JCfKWnQQB&^e7BUcZ>Q7?WIP.2dP)Q#T^gd0&AS-<EX<:^Q?j0(W2#REkN2PO^hGcsBpR4jkrnC0,r6(XTZ b>0L<&@4\LB6pcW "VsjB@0LPLMr 7qm]ga1--#P3;Wf4FVM;l]I)[Vk_^:IiW+KG>(,SZr8_%Apa0>SUBh<AOT:YAio-E:q1Qr70gp%.i<*i=k poXAGj8qNT>AW>VY^3\JA\$$3;<KZ$4.saZo8V[QCi=rn.`hE?$?5]lO$h+`0]tBa,dW40!'s-!U+<A1"VH`UJ'_7A=$9*$QNo3.im_qr[5e[W3A62TIJZF%6>RfIph*9P\MbY9llP22N1%o^Y3oU2D#k)*W DCN&1$Y"@TSp+`4c7 ]t0mh(IG"/AXZ,D?i?_-%l.I#g(^#Z3%g'RmB4Us-T`G]:Xo'rE5ZDGl5@</<6WW$M%$DTW>,]3crC8_:^HQF6h>'d&!%3['k9O&gFO)r7SEe=_]=6Oe;DaK:XZ%VNm$o%'>;M>q5qH8@DFFXFU^t@O8DQP-J*'"Fj+N4Ur5[?7h6).#+C[:J6I39>Di2CF+] Po"7*"Ih";gA/nhPJ>EP_9"?e*m3*UUAT##9i7eS%T[/m$%Ab, S^!^X+DI!tf?cN9@!t*L[2NWOZPRfc=Ao E$AH=\("8?oe15>dT!B]T<ro+:pAF1`'aH;XMr*$U;)p%9P 'Hkj?04I]Sl;j&$(,S3IC8,\($%XND-+i IPY]DU7<HN>s`@PBo?d-bfZ")mOi#$b2J.A3A]Pk<c;`eYeeN7\kR4>RtQRo Fb6G4YJcKB2-i^Nn^t7)dTOdC:/WlkR1IoW)GF^*:=YFA>tV94KRfkYnFApkbb^qLqkc`7 K5m4"$[\RIIYJ-Ys&Qd;P&RmL;fs#2=V1LQtJ[K10n+DYg&ig <Z;* d48"QsJ>eYsEbt4EjPP@FsaUjs+^[<i4)Kh$2fe(`<n>b%GqZr_+lgQ>idEMS+7'V)&=nn_m1%=G6ZLP8XTP'rNo>%[Qb4/4seF[&XSB\EVi%!S^SrtiD:ARnB?3As,%L@_OFhm"@:'/=N*A*OMESS2@M1VpaXTd_ISUSkUO@ERQE`SaJm%V0BX$#WAd9Q>_#-]SV'[:N_,_W4/BeP(<,PA+A#lQc+RF![]Xs#_A1Y3Dl_A3,kXp@OXT(i'M>m: +#b9+IMkJ?!94+p`q0Gb<M341AoM\MbiCE6La`EcY'[j'= =k2>rae#sVoTXtlbmSFt(^3P,?jpp#&H/f#9T8m]UJKYT"N?,36RDGgl(5i#j]% # XE>6l$5^?0&kKs&9h#P-G?$q1NMUXc"Y[Re</N>1,K%2RI3D q8?7J6lbG(>jT??)E/F8%MmcChF3Ie1M*d21#"p0K<UMZ/)o[8A5qd=Xeb`3feWnq@2P0a3JZjdIIJ[;D7DLYK-a1KF&Nkas?7JI_GYrK#aiX`P/sm%a6@#+2 BpJ:&D4D)GI.75Hb^MA #"HRlLD7em,F[bXDP.qXNo,`.+%YMNl PKmbRE=Cs5btD(M^QOP#Ka+r<t]Sb%Pd2So',(=Kh@\_(s@T4H'7(X2Ss$N9g7(CjD)nd4f8)^RS#:J7L=ONW'=1(EDk#t\-*fYQL#S$BE*M%g:XWfFKmX9.c=d2p7A/m:g/9]\SqUb:p`p(TX(Uqq22R`1AQA$571UcW7EJ2G&,%2Bm;K=bb<Jd`3YHV-A3h^dK&F$D[[.'W>n0:Hp?8/XRF! $T%-<0f8c&+DV[ZCV#+;a\c'<+^"e`A8+9!<03(<FU"Ih]^.m8SAAI4gP#Cd4!onbCf]W)678X$(TY"C0=VNoZn_4%\4 #J-j`+:M[!LF)feC)R_1QWW4G'0`C?X9TAB%A2h@P<NhDD`%R&*ak3-(D:%-UdZtdCBE9C1ba]'A$AZI05+N>F">XTr0,hl-+pZlKA(9a\pCQt:QtMjYYman]4nI]-kD@`kO<D#+'42ij=b"N1]!?*-XAEZh0;3"n,.'E,-2RDKfs*$*pVVY=AmkCl-6)GJZ1,O@lBL W6Fm&"J>VZX3o_`Jp#@\q+hJ58LT_8El&d8%.%=o(,!f&"Kca$Q),D<F>BJ)_FNob(/BD5Jp36H;.R-.(fE(^HXHeUbJkN>X(Rb-<o!=P5l,68d'GSP.OGs3O$VL5?a)]XS.5"j!CX'=A2*O.K(3Oe^AU3Q?9Ft0Llm1Q;%"4HM; i,@h':b0Xo/icY,ZV1"W B .c2gXih(2%D(Lapp>V!k1Lth&XdW-Afg$@0'@[bcA52+=at?gA;4W#354d(Un]l`=+^_'P+$pA/4&STiO&>t5#`HJs4V%DTF@j<D]H>/.6Z&U<Kjt"Zc:n`0l^#]OBhO1]jInmJC:+nktQ$d,bK'NBbgX9`)A<ZrZ 9c_#f@*MA$DMjD;qL@(^.:$U+!EkPWp+j=jAMjAFn_+t!V!d_ Fa%Aj"6eX p28I4Qf$FkAfr=X3s3*C`Pr-^re=d%qRsqE;rn4fk[m0e4Q`+kX)&I._QTN\^pV(0:TZ&i0-d;(m,_=:kYtm$^[#g$06k(l+()tKN19A#!QTZ>>'*[da%>TkjrnN3\L.PS>_g#)Gk&fXrqGUJBo+7"oS?U5UeE<n6NGTUJJ3`1O:JKBdYL+oC _`^>'@A;Jo`;r9Tc#)Lep\scM8$--A2C(K?SZlXU0E1M00AJY+?XnhSE7WU?L l!S98_XBA3$ddc"!rtUcTDOe9i;hk1R+`k(?a@K1lmZk5:eSAo*Q&n>Xq`<`I/sg*Lg"=Q_VO0=pgqX1+C^rO-.V& :>rMD^#Mc@-!f--t:KR+ 3mC%[4&nS5!sC`E_W,]A?,5CDSA]i)k0pj`_ne@Fi9GJt6q-d]jJ-jh4PhR(KbmDgL9p:KakJZ8C"?iso4%Ar\5[!Um,i)lgXB6Xl-*U8V.Nm<%7Esb_`?*7tTMqhjqTGh0.3[%6+@dC8W+h(WlR2;27:a6_O$5k3gQ_o(bh*IE0H#E<PskG]_#m1?XG_+L10:\U#Ra7,63fKDN#k'pfYc*/[F*UE;dV j*UkX#`(jJ2@n</rWokA5L'ldIqt/[eAC80j*eV8!2,.]>).4b>9bm<%NEI?N#&GDtP6&N>cV3.C"_:O.=!23?!?3LHd5m> NRA)lO3c/d+\1A[QB`C\2U+57OpQEqSc&]@0AX!d,\l: H sm<"j5'(d"[gHX0Y"O#`$hU0mOkh01NWt90&rAen9)NA.io5lq#do>peBfp<>A1BeiI])fe!\R)]1\"OC?0Fc0k 409tn!#qQe&N@*E[FLpPR3HoY,PS,%8A9_iD@Znc! Kp*gIhA*nI"`>;Tsr;g[R`1cmt6"Fj/Pd#gLr!=8XR\:Amg \")eFXG <]JL +Jg@`MOD7a9Xe)C0oZPBE4ikP.QT;AD=3#d^t3sn1il3qM)!2>\c$\12;!jkUftXecD"IYgtr#2tR*Apj$rRT:*-nUY5]T6o*fFNMq#I :.G\ah3sq#`<QX_A()=YA$;/ 2,C43YL:Gn()AlA_5L(Ap0WpptgOlcVD6B%\Ja,4jCg?5\PsO\m?%bNtAnK&!$dR$&kS]3$S34A]Gc!qFE q o1BM_IsZWE875i"VIQES:tND# Vf<hG%TCMBWfmhtI35$A^]q49nrbnaNaomsDpZ<E@jX&so_PKS*_)UbsFT\4A\@NNkbN"_KA7Qt7LU-TEte!XE?iAL_ft_;,rT<cJ+)U<j^TL%&!Qac,@ET$i%>7mT[;2tW;U(Ps(ohs8?SStj13fULZHM2&-[9#/q V\fifI8dq+Bj:NCjEpYa\g<1ef3>cBJ\%8aklFb4V<-A3CW/+L#C(9r+XoaMar ,C:t>6r[KYT3XC#5Sr1oVW=q'/@58a@qD!/X)A<dg@Vp7"<>A_LrB?Z^V?j=WD)1%eD7=o9)Wti:`O3"]r+>KjIK/K+3+ki11&ciJ4+p>`lA#]p[int1`QTg1/K"d:CmhYG,h&@F3#>h2dZ$kYPIT#Bmq6m4f,seO5R)Xf1Fiq$Dk[kHP74lN>^mapAnWrCiSb4HsUYAYr++\**e-%UVjtfP1S7$K)Y6 0 &;OPXKY]L6Npc>SRHd`?n#A4O3[:tCR4*!;&DQ5c0`lL!])^HsDUJ #<t@+c+TaG6ScmA="V/,X%g?gTs'`acLUe.`kJ9!*$=!YSjjk2<=@ZDLlP4sEJd<T?dhb\%!B->&ZO1bXbe1$:q;/Cf:bH57oUE]H%iJ6H8^em60DEeAX6WjXhV0_MiJ]tdAaH<oh,]j+P"R^e0]sJ$AWa?XnK]hGCsYgk,ht]_7])nX2*,+?3eSeA0L^.OUq6&F^[IdF%I#ofm;/J^W#N6N,7(>o-k8\6FSN(a K(6?T($;dRT0Po5\MJOXqg^pVOI[.W<8\3Nb(s9g_-P](("A_3$Ra;b_tSYLb W3RKP!_JV9],P.q!O9>?Z0d^53"Fi+J=bf/0RFnPa]'f"iY-g\QK+ir!K?H&MK6K'Tm:[>+j7P?/>mZ[s9(/$=sU,q787+2bY U#h8<,qnUc6tt3nJ[d372 (WA&*936B1%+9m_]j8m2-Z4OOHppbR-GXQq!s?HhI:JB/4,AO1+b+CtmAAS.In[)=AkLOMbmcD ZP%sqqHrj]F*BeAaso=.5F#BQm7[`h'3l\3Y6&!S2j+pX"]Ma8M; X``jhK(5<%Xm_(DbU^I@1m6qGk0`2hXH5T4Yaa/#m`+cI4UiGc#^Sdf .">A+&!A:gW_MVb-TC/S"c^r;9bbHc6TEtWemNqNn8bbDs9=pGi7A(SoT2d&=Fmo6W!o'haZL>GG`9+DebsocV9q_T_g03?Kl-&'WqE%>sn`4>cA?_@-`p64Z.rVFfH>t:)d#Pe7B>oK&Z1]D^A"A%2`kh#>_[&o/HXjhH2LOC$fW$I1(.?r@VIH2sgDa4o4XM(1VTm4^!Ra6`AD6T;U9d@$;tNR:]4k^ 5l359gf'b"AA&9)^.r!>hA?)]]bW5F>U&Si$ss'7_3,6[`]Acck9AC8Ca\OL3bb@fdQ=VS(G=ieci2BBb_jFq)9L8>o0J)DAL4<]VG'E\a!lI1aEaG-$(3`N 2VrDrQm+!>t_O-X`Ze2 $mI9WQ2T+U;\1P;aAgAHl<i"40L_(Tn.U/97^@]3!EP9.!cG-'J57-Ri?Ms0')8A-_4WV18KJdI%.6W%nf!0I' #\A\$lKr Xsn#T.rE)1"1MW1pT2QcY.Yj 5YW_?41a`<H&MZc!9V.LW)J-8R)D:i#B:;dHF,O9#H_m"U?3D(Ml"BY$M1;FK(#k!8bk3[PBiB?Fq;4Ka]FkWHOOL*kcE\-<on1HJ'1<>^Jn.;-@TX2C.T2J\R9A*--2kjc_X&sk8r;^'$AoDON5=bbk6?1,0rpa#+R&?pGAl8f@_])G@lF#N=_ 7cLY[8JYO'k%d[XS$ LdF@lE4Sk%A_AZbP^7lZb62k3p0?XR$q74j`Pgc\Bkdt!3CODA5Et&8@!:A&Z7B4d3q2'ZH.EhAGt;rWYYo_e">WQ#417A<P=Q.$/)#Z;W.->Tk%'Ro,pS5;`5'&E'<PHZ$\62j3+>\XK>2o&B??IHl,4Uf>95a)qR5F9;Z _AS e-cWA!;?Qc,UiT?iHdY)5rQgD*:"-:* /l./Q%&^b)_`h@37IGR*P)V0Wj0<r[]AKN-d>.RIS+t _UMJW)d^S[snLfAocTL(GIB6ts4tr3%Sr6^S&P8:npYaAlVC>n*D``6F)`7-pdG+L:e_e7MnrfSJntJ GQISBRm996%%X?c<l?G1T'A@'Ih!1hp9U*[Rm,Y<@l.:'.i#`S0,nW6hKGn'\):IB#Na@$,5JA,VP5DnErnN_\>tKSm0);?L&`D0E`[;\Rc-9c\ihT/;*9\j'(V"-T@#>lgS$0]^Aj04nKC$<9/D(2K\od'XbO(J5F9PR6=BGFp#3l[p"n30&NEQUe(OkEiJ8%)BAPiK]L"6eM7Q)VO)FE\bYk;*,R %,K$,^#O2eX7#dEKk>]5(Z_p\B_Al`f1HMokqnGU)L8&AWEbl"?495+.`>IO;o0$d32g=b%W=n[>9Bn$iaB=Lr[gP3ZU6;htm_J^EpNtWp;;9cXO56Rro-'<r!L?`2D:K(/b9_eS&f$AAB0t  P bh0 %^X:fA#W=$$qOZ$W_O_(DVXBMrUPA^_iidVn"5CH%9`bmGMC+"C>13)&C?tq_CX[g'QtQ8fHeQiarjm3ha^q>L@Fd`A'Vc$i!FiSXKDh=*Z4(d6,`.+K>Kq`Np%`.4TZ*d-BAI#/q[Ns+(g(]0s:X,A08)o7ALtHHCOOL&@NqhmikX 8,>=;]!MCea7RC'0sHWnW'L,7E7'+o$A%t2Ff$$a(pZoc5_76#cs76&,b$n,XO;@M"5VRUld*"q7D+s6.kBY]VbTIQAB3PePkO9gIKTSVnZB&0m,AA^?_QRkk*\;:;UiS'6`N:;2.H85:h2ptSR`V24@ H g&F)&@T]A!Z3EdA\L$rnd &D9TN"hCrMls<r^MSD"7SKAN0D#NPe1n<<;e/%fhZHOrV"gLe$1j8Cckl=Ei0\#tpYJ?*pIXc7W,j7r-25<+K`7qh$,Q?DGdpNA7A+Ph<NfHb+jC)UIUt4GMo2rJU@BF5F4RBK>UiJ'Y9Lnad?8r^;^;t6Did,l4\5%jH[;fPN(0.ReEQfRcidVVY^lX]F:71LYqL;A`m$M*t<g]c`hKg UrJt>5(]c5d'A8%"7%!r'mtFDUj.+g&S].*+?7^DXAL[s+/;f-'#&sk&Z*"b\pcchVBdi*7k-Xf\+"-#A-AlbL,NfbcUf6">]^*PmcEOGU4SKjp,1&(]?/.rqk%Jr:UQl3H!X iHpMOr4)0ZB"-0jMqA!>21F/h@%_X$&)Ze_R?_AE$YP6o`,\6&L@tnB#Ja$n,YOF1;e2AZ6;>r9+&IWK5N<3Y'5 GrJcp)ZK>r`TXr%8QWs_m80GnWE[L%geqW7P_6XIq!-'(imGMnKg,ZOUf='#d0[b#&L<TB]iRhVkR>F%'kK@`;/edX)=pGqsjOnGG:467Vl&r4] SJ<NVU8GJ9IL[)HAh6a=H:C>%sI%/VQX#K363QfJ,*YGK(1hHf@G4'lTTTL9>>[T%'I3>rAG-:r=GnFE41HgIo=&PT[^BWH]M-!;W=)Ad!.MUs@p#[:>lmd9&^8 ,T_iP9"Tj1ItmHC;-Ib'[r,l?RRV2$V-j[#;h:HK*P8?l+h,$#=t$D,%-Xo)t2#)RZr:>T[i(jlBc)E+>iPIP+6h<Xe\\5FDAX`8@]aGHjX[Uq2k`tb<DZQl3Za%Q39bpPI'RT?O[M(/UAdRsOEqF6A=6#&_G?aeNHYItHQ"Sat2R+jpA`,RB#H9'WVA(45m#,FAR9&*7TK-I$+UgGmA+R9 PC%^hcZpYmO4f%aQe^"a)DC 3@cb"p,>k74K<ht$pKfm #fBm\3J6"!RUb<=g)Ob9@YV c7;ZZ$3=eDM&`HY,"J'7Q=`AhG6m97g(n=P2#e>WWML4<r38Jt-n@Y+)@h%'XYElcDEFe.dBU^J2/*[$3'I7>*3Lq/<L-5;cdQ22>#6[bn&_GsnLPMI-+cl>[mNdb"nl-$W']\'KaLPNA ml]t^WNOt\W3aS\7]"D5./8lS'5g+Q+<?pNBpNe&M-^g/fL<r!@@43)&t_PR52XG,qil%WH=^&Dqa/^p#Xq;aiNgpGH@@k%'VIOgF=V(fbAWg67@ i+)6W^*;nB!sfa@,"e()fk=""j0&Mp5<`KUNmF*bmWZMT"QY(^3'1L`g&c+,-1JUL#^_4:S8a1c^h#_8!K@hUa>hlZ&mm;OK;f"@%s]qkT1n$T6AHtX0FM^en7eIdsKZ<60;(:X<hIGAP4WN<APS"*D5E`]0n[/nB^)AJPf>88gEg1W@9f&[Y#j!;R_\7K">Y"35C0IXdi0O/$/jm(!l+nmON8=2T8fe&Tpf@YYJi;BrB9Oq&5gDl'j@9F4>/"5J0/Wg;ApWb::fBpp[B'MCUCsKnn#7Uhtp7BqAtS!9f(@Tc\>pYD& Cl&ZY*:5mWKZ3jDVXPZ2( U5KbP]\)#qAK-^NjVd.b#'qk>#F.Gt?ZK@rVt9FgG3mQ;iHIe&m57(h5G9i/8n`:G&HpfXLD:\g:RXg`P)X\k\V-`Bp8Q/[UP0<?RBLNT5Y(!"2fq<(-/q?>OBCCMHY$i"X61b>q.Y^-7K8ENOXTF%A92nmd>72e FEo(JD?ZNYM80>_iD+1.R^H;pK=AAqLFXnDD>'@oV5,tZ6rpcpAh_F-$A(ljbg-bS>N#i5 j%dT6I_[?_$`a-*)tAjP Pf$e]ak1";1#G/\k)%+c[/3P7\[qQ:\cAE+4M>^;lACMfV$_d hcesHeX`,E7a$_?sIZho7V&49_)a<JT* s9EW8"P_\!"QD)_0\bjUYH!80P)l6:'isq!t4c(Fi6Q>>X9]mhD""gYjf[9K1caC:Va$SPl_KLHR1jo?Snk[R-l$`'aWrA@_Iio^_b!2ZsP^Vg_6Pr`8@>BdRtLp2_G\#iSoJiI^jAj3bm[=T"<h?:%J)4^:NG3-SQ\'hOC/=s7mo=CGC[=V""af2R'=)]:f^0gf:e]"Za^>@Si FfG?o&r(?"gb>% =(jheYkR(BWC_H^Ki=1q-aZ=g*h:Ls! =EMTN[-n2 [MC9*d$s2tn'@0fr%KBG"6k784fZ Dg%OTX0PpR7Kb O5..q`kZ]CmirOg6$*Es#<5VXV,Sd1X*$*oo.&ak3N+g80Uje[H0$l+\1I]*lRi)6=h?T9FOHk+>)JT#a))fl Gd#/"!24O6G:6@PDQm/?4k_n7%[!Ei2Ap@VXmP_Agm9?=F:7WeW $NF\3C0%aI>G.ZNDQLQASrn(hjfH,.Z(kp@:<e0sjtMrSpU8WS<PS:Dng?D,8mWo._BL^XoIMU0UA"D-TYo=&pVOLi"tk2X?4r[GV6j*I"G?@4'&Xolk'<.ORsC79L^DjIj:!'C7q3'E`CQm>&jI^.?T2rLol<;8<ngkr4&1']A^?U1^<j,.oAsdf-9%3"P:%f:)koC-FMa/<se*FN+Y31l;(18;>o[P5tS#U9%6Z0UJ!dqs?(d7Lnm<'K%_)m6n^,IY;-j'OTCZS`A*j_^b-G'56kcZ'IGa^kNJF6#.=X4Y/VFIG[19(A`"`KjoTcQHfL9Q^0jkRNZK5I>'&YR#g"6.(A3nU?OIcnd+QL[&jN!<!g'`LOUoTWPO3/W^R^`#a]'En5)=N,?D;TmBitXdG0OG!JD=5;HkkOY>AVN];igf.:E*>tRBO:S[*mYjhPCJC)8Qg2$s+0AKeBd4(s1eZ3WD#_bVo'6m.)\&c-?V+f9=&A_j4L?9ZQ:-c'pW74U%r.m#DEH8f6F7H1BLDqa+eIq_cj&T]dr DLjep+oNt93$T10 GXAaL(Dsb(hT&(:FTX,OtVO\9I4#2%boc,0Gh5p(f]'bU$L1[0ZBkF#?ogBjUm2oQH]pTinSN":cD_FaEkA7_M3\*:Q)^WUREFZde1APMp`McO8pe^:-^Y&H9QR,#+n_JO&0Np+9re11>)YM]fYAIkCACaA\3-7fKIFfY7Xp[s\oM)f&*+p)pFXkpjGUalhQsV6iCn2iOBU"?19Ns7.m-_kh<-qI8OlU3m<\r;tM=]]b,/.]'%Lm*Qg1%jGlE4AfWh5TR,:nCU3ob!)XMF@^2%s<JY"@\>Jdi,@/Am2Pqgsa,nZm;*'%^XK3e9R!96eVbt'2GkO+s,%\F1Vcg^W"s`NR8eM$?&'MA?]^Kj<@nS75,jA-V,`;<J;Lj#K>=V:=p*@L>_Th2>&7TI=,.m;XE3142Z#0$m$8&(!7EC%J<>+$t#-;-"1EVJAW,`AkjOtXb:;IaS#q)lDk6J_DZaJ-P-7?]MO1XrqU4ad)G.lD%aH4m[:`_Tg`5^=Dj_nNSfQ446ffRC<t@?6VaNR/1fk*@-$qb%t#j]aW]n)EG5XJ5:K*=M.R=)eAgsTL@OQ?m$#6t@e-eJ'_J'1BRLF=gWN6;3S*CHM_iBie]VGUeUGI!.0*DR-\-[9L\mWgN8ebjtP\$S0?_cR??[`HX',O=>c=9#Y.j%AtJ4l:+H2oK`*5;d9mAIl_J5LX$S99sY#TA-=nB*G^m3/#T^"sLOb4Lg6(nGa_'L '7$i;bdDq'j@j5ME_s1BPYWDn!j2Z+MtB8*Q_V#ofZ7Z$?K\)g2Nrm@-6S@C=^tSl)`T$bm2"p3jj8a^UlME$JD1#.XNRk/$,A^g-\nj5@>&!-mhJ*XYNKHps?' jG[*S"<piI0HQ]<)ob]%A$>lgP$H"CGQT m"hkHk@U)N?"dVp!I(]]0$0;kc:)Fr2DsMXGZLWUFT.s&U@fk4$L5F*j':N&X(DQc.P]p*0ai)'5=^6r4,)%Wi]`O9,L`mPj,pJH)_S*IoN%X\[X'A+RoetZ*q4b<^;2I85HAbh%l5kgAJ8)+,bA1nL!H:8&F';1!V(6D'O;KDE&PhM8oRQViRNV4%Vb@Ab]qpP:Q^i6iqW%/'m&kBK:dd=j58ITNR+CRgI(g1.69cq'B+'+0Y[5[ti=]$0Pe9=7H>s$oZ,6,^iNoNJtg8,SkCjpYOPlSoZ3oP^KF-s1ME@)n?U*KtaWCpCSAFK?C*CGmr4;hCMd3]bLI2%]m*4'aPg%K5He #TLa@#%"_!KItS"4:;9lZEoTOSI6['*(_I^@qFf0+Kc=f3E.`(0hiK&C!jq/-@HQrk&8T*Y4\S!%q"-1H(_:-\nR?O=jKMFfFin0LqO9#prAm#%HHt[4jXK.XFEH?G;""Q0O\5>;jWL;5@c6E;`61Ne?G'T+Xp"-n7pF=#N=@@ri<G^jf oU\UK05 3*>kG,/Ze-3hB==Zs@:OY\AVX=_Y.UotK-X8H;Hk'\U3+dg?Y.W$_Cb=KUbm=j(AYc\CZ%82=JWY53$D2p_qITtj/.1M+:SGC/b'RJF67h7X=gEREg2[Z[9LRM$fRZ2RL4"r!`AYn+jVpPT kPZBHSJUq?AL!fBo`\ ToH1XVtBL0(r50hV['=UCt7Fr%@&e2K^5md;r30nn^'BL?Ra^ZWf&Bo#Xa@_FFUics@m[;tt)P!43p`hR\@O:eYqdAjmY-K<D6ZP'U,:A&jRGH/a7-LA(_J$-Bbnp%Qd#WEtd1HEq@6=lLghDO-Q%CtCfn-O:W*L1T-QK^ptb':`S)`]l7o95VbO&^CR`teXGj\:PAG!p;&3$_a<:a]JCgK5qI]TE$ipgnNJPV'VY`i93SbUqEL.t$O``NT<+rBjN V$-G5Dq%mO^AtlXC5b;UpaOPgUEgp*r"QGce/3?8q>7';gQ6Fqp/rKqYn]BsMO.-UaA$)#=-b:di#ZnVaSG:)*]AF]]q3L/0n<!AD6bAM1NNR9J"WjH4-^lnbT]Jo>GU"]2E]MLh-gp4s'QhQ0;oq3WOtNCi:ZQBf,_,"3Q;T&] XFgE'rg*;?MD3`*=N-7$#%nj9sUC%XN%,h#CA71ZAk>q%mKB0mO2n.I]h-1I#+!Y)n,R:rdpBbZ[BHlAV!q2cs+@PSb""Yskj.A81 A.rqFgiB6gJpSc.V3N\Nb&jJYI<(+%QZa7dA<m2MS/'R0\Bn!8Zp^0j-hYAjA?+iLbi)*rl,.XN57Jr0FZ7j1*o,#PD":h9O=tD'REC!#CpBP&Yk]MWm`>TpLH'H:F^3FS;YdGY25_U PeoQbr<>J<+Sh(`$P=kcM"0nV\O<OZ>#%lEcGnrN_=X<pG_^5Rfk@p2UPaY%&Q4>n?XBT13k=qq).!E4BsZ2"pqrGU\;l1<Vlb',Si]XHN</7X'l=SfIUMG.RaBe,`$fsp@Ug+H,f<)3F`ge1sNk^*Z9,cAS!T1@RJes"64iq'p;T2+J<'Z59S.-6<,[q?gAL&kC`I*?:RmKgCOsIAW+M5)C8-POb8BA"-JYggeM[-QX5I<8F#!g2H:8LDTcR4b*K_!@e#!!SXX-@='t5BG7o,QJ26>r:re`W>b'.nrZL2I_&S3A4OnVW6V\E%14qSG]FQHi?&2);SqGFPZ)q%bn!O<A' [7m*@$Y@IpG-3^p6Z3lBq'<rUH%^CUir,Nt=`ikL*it]gsAn,Cgd_SBW\s?=l=%D!%^R]Y:]_FBf2\,Y?@Ssfb6FKNrT`=]lhPXN/D] 8kTXTJ0Y`WR!jSp!M"(9TK,$s%=e9QT=?rQ0:q-; 6K0#@pIIYSfO3P_&Q7-,OaT?EjZ 6i.5lY8Zt7-0?0%D'MD4\*XE9!2<6@qsp-E,VkmX<RUUnTG>s(*`5C^(*>0`8f5.D*9CFf8,C3mMpmdn=5E!X+9Kp8'HHc  [%Llr?t-,*RX59hS4_I7gl;;k;%qG4bKscD+RO#go605<^JCZM5pBcdA,oJd'75+Olr=aUe`l>[rL!36J" Boio2$`)Kl-=Mgge*+@Cssq1n:7KE(pZ,2$dY.AK[ D9qAKrjo; ZeU:Xd+q/-KAI&1Wa<VO*Xc:Y_QU:N?sXKCd]R*FW0\0L!O"k,?C9*r:$5f=oO'g]-o>UhsJA4i)R17&_1LViJ!EDpiILQn^sp*1"$s(^+^&]57\5A9G,rI_$&qFSKBff/)WBe!+6ka[k*YaKYG<0RLEA,t:_"g.Y5A5LdTWl"/_UisPLQ:O'Y8-_`.4&gHYIj!1#PfbL7M]g:=hT@M>6<i;+gpeZj&DM:n.3gP/,>%1-t,!2*nXtltI8#X#<)T.L857G*F7JjXq3:n$5q(Ad(<V=+VjV0A<<0thM?eA0a!=8rrO'D,tpXh+GbQJJR`Y&g(:"D%`V<_q%Y+s;R3d('E*]+d`T.ALoYAJ]U5nsXl#W[F+[\n>8>7J#H=4si+]U5\AAE2PP/h*!cEG?JM0:8_5aC1o1.cI,h'd8B%6BH:E<2"]rrfbOEZ+=q4t$@iU2hF1[AmRg@>t=r);Z 3+Hbd4PcHV*i@Nk_EMD3?Ct0P?d<#A:5W_!F+MG"&kK]4j]-Xd Q31oql;?O7Qa9t@bNSe6A%)hRO12E@VNcsSf407#@?#92KeEU2=b<SY4L[?2mL5*80pj.=3P)9b5/Ri0[:`lmE_LkT5]gLKa`\V> oes)XZnaDg[eh)3PG(*G>DB/:^GsR^-)WK<&BA1K*2i8gd6L"nn2 ,8Z4O5[B22Q0p"r=T .]Mr6AeC[qY?5W)<t:nIU#1d[^3i)?U[nd[psX>d,72#0:\d]T4LM-2d1)>79[4qAVkE/Z^aSB%hq7@UL)iN!Q1=(-U+2WIBqO_RU\L$rBJ(q9oH53n9kBB5lr[D1*/fie8Q?LB\M^0dIih3Z*^J?)Z11k@,sa:p59]G""sB#2Q;LX@?Y%NBt?t8?p5FZWl_S(g[!U`oD,=A^_]3?8n'FeY(>,kqnsFAN)9nE>;YpIm+#\0lD/:mU0jDZ0+Q8BD+G'oAMtV%EC>FNl6Tn,714bS2_f`X!lJK0JikF#nqYP8DSi&d0+,%+CVq+V4pOd>Se5meYchh2-f4Uksj'3R[m43qh!'/.Z^3j]B$#CJZqjWb+XLUM&-a`^0)b>g2lFt3Ml%Z$g"D(i#H]4FbD E9G+BtjS?8[1ojO:";nU1s';M]F[8DTpiNP7iaPnr(/&1t,EW!f Ige-AD?U8EUET:3YB= &,E@JT;%7^rdl"-1A-@YLU%?sXNo?r8m,A[-H/2nS6#jEPYnV%?8s[ZEKI#;th?Gg`=[r!O=(PIh,TBX(g_14V[jS*oaF=I$]1sbg[.L^U^;gh(YWfco8K*Yo_1m:Y<9XcMf`cd>4B5_)2tP$jja#:\4!Q&4b7GY`NoO5)l:-NSdZ!odhsA<0YX:T`=U,f\%TD&t:"m`> M!V92(Df#!`WYAoBl/A#NLH"XGVXhdmrjc+[)dJ*dXK,\IGLEm)lgX-\MejV&!G=Y:j-ck52qU]f:?rkh:i7<OD;/I$4a:cAfF3^[WHA5&SP$$p',\i+GN.q@!-$`L#&XN\^sT-BrlDh:PdqS!e7`WBg9t# Y6rq:T@PT>?2;1Q-l21cr[\o+JQb/1L2)t5^A(K(9BMK8ZALi4=<=tND"j]nXAgtA(i`T%!"+;A)nFJFVQU)$Mi`Z:1]_AA[aVB@XD>;h9_6WE(l2Gt>I:nBrLcj(nb@GM"7=g=S T\M 6Sqi_o/_)cOr]O:QDt@qk`:jA4tO^+:j#MPV<1kV^;k:)$;)_?,mGqe*AY8#Ago.k. #OY5g:>?g`$qSg+7\>3k:ak*qmj; gdGUiig&5U,BYiB?$QXWArV4Kj*DB,%W\1*9ES^lg^=HB>8qa4%Pol\nnS8*!r`%4Nsqr15g[*Sp[--kpIAq&^N<OKL/OB'(rOcp.)'AAAgj*FZ^flc#UCg?%BjJ+>b91"\Tp_iT^&m='FeOUT&X*ni*rD\0P%LKUetBDK3A0^^EX08qjg+O2Wrc-@U"`M"3R291mG[$7G ;>pnbijT<Q]2lJnBc@@ra"WBtAUh"+Go 6U6,<Ns]kheJses]+A>)6F(,$e?88$sX>=(P;!]7e(ht0^MgQ``%7KjDdCmVbV1SLTeWg7PE0g[:e0Q+,4VPfHg+k78Hm^0UO:Ea$>AV\hB0c\#Y3NZiA$i(hPh>PN@s<X+e4SOTp\_o?B_7C9t=LAaM>_bKW!W_El%bNg^sA<)b*p66]'!R*Q9(K4'&YfSUHY>`J$0X.Q.m'j _%.LSMKF2 hcael/5(B=mNh&#@7pb'ZLR[41U60[S2L\Fn<pn]6AZrM]ip)-?T?A7B[dk`7?e.CI-9a$ejs%(&:bs,HV$@C?.=2)X39dM5i!`;h#@hn3AO/ pmFMOpIGA2t*@>@eRM_2X+hGYM^-7[G-^h.^4m_d=(m]5DYm[g 9)kF0/=]Dog=hA`@.A!0&'kK'<dg]69t`mqqT!q]K347>#l.2,T^qBde&[Wq2F.bl@[(-?d-,l>[][34(NmM8*/l,m/fjif[+b'7gn#A!8+H)tiOIfY-VqEbFZ_*d+(Gi3n^cWGP9"I$gpO)Tn\@m848(OA=mL'MLD+#aS^eo.mA0cDK@Ug5O`ig%s&b(t*&?T"O3RE;'g33#cEE.Q>B7Dl"&`\[DF;(RL8R9@%l'e4s$(;7Q3(Wo@Dg 1?GW>,B#9f(48d;E3nkY::p%B?E]4rUIIl/S>_Jm)dkbsPX]I1iedL@/lhDr+!)O_):A4=cK\S.U:*t%V<cAeeA1*5[q>?A3hk!"i-Cgl=KA6Xo:/DJ##(3"Nm(Dh+j>tg;ORJ.t'W;1=k.C5W1sm^T?g%slq,RG37+!"TtcTI$U3UA+B+=O8'F`?mh^5=beG\9,e^69I]@(&%moD-N!12*d]<.7Glqa!*ddYLqWLO5j#$QbW0oJP7XXJCRG,iXOM9&\=[HQ"L_I)^,EpN$[A@0&VdqbX`E[`UiCN%PZABVibPN)U&/l+h_E%h'%!t^k?NKmL9?1i^nB\OT?-_+,`*X4'OH8h%\#],cmg1Mr?M3elTGrA&po0n.XNh9Fk*>h$[(Ol cr-K S,)2mYCtm$HqMh,d(3$Q-Er+=6S\YWS'2tE(6">0]g3D.9*7t O!rO1C-g:JTq5Fa/>MoASLgTj9FA%b<sBjKpDQPe8HaMe4(J70%NpK+A&_>*%I\Cj1.jgkX?3n:,#WmA;@EUAEa&bJ$?=5(D.[*4F2ReSk8pq#oOWCW-k$1ks=<o'B"1DB_32:OW)fXK+hR-BpGCdDA5iXgdIa9s.Od6n-^L$A+J,\X4;E(h$sJYXmDel0FK_.ng-;-bKZlY)a-=iG>hN q& (PUA[]iq(elgSlXbZS"I%$iOcin8,_h<*!@@N\raX+JL 0Ln1GTjgIj)d,8ZU#A\<84AiW'@s%#FZ">/ #JaU0hgBgGB0!Qc_RR&rQQh*7 UR3Z9@k-(lDP)XnsEoXt"An-;LA:*4KrF*13/-n;Q&[\U&X'&e97jkU',IY7AoppX5nK<Z3k/^J)A_I`KVGU+X%&) ALWm11a.&;#V&7LYm?]h^"?$IblT7cE'ioPMr7APS+?iaY5:SnJdN?i$;hYAooWQT-oT>Z#s2JS_na@R6ZF2m6pE+%-"$6mt.t5\/:rcnO1B%KC@ r4sr`p0'RoCQ=lfNam6;^?dLp<SJ"di_"pHp\=@P!2`)Um;t(gRmFcqVUc[FA"*9)AbM,-!Z/7Ge@Ad8e<WP=aP#SS, BfpOcB-Sf1NH# #_,DkoqZk8?ADO34bJWaG*mdBVcPt@N@0nH&!!=3:2'["U_[cA4VYtFt6tLQs?l<ibB_:_fi[Us\%@^p<AU8iI<7<YbCKP^ghShis6,Ob;I ^>.'3SX;-pZJ?b,kdd;V 1#KB8WX4`Yd?ta$5CGBdo<U=Tjd;KI?tN-6hah Jj&_FdV'K]M$] r-]3t(++pSR&Pg$f8R<`Al6=RrCR#3K 59r07'5;";`;_c6&0HR [,RSAZ3%<1G1YdP@="),VT:Yeir44h=n!-Br-"a,C,+E@WQ$*%]/Tn`?ZX)=,3#$LNQboQA<!n6%H"YP\]mB5.;NX1pe'?`\@$^BNj<tQ/8-PpUdj_Ck"=&FO8EV0 ehmnK(Hk;n:fq2;G=_Yg(Xo8sq!*VSd5qfW!q6M7@nd$5ASh^2mm/[7rC/k4]5^>1" P+tR< ^o<i@X5f)\1:5JUnj+ CCbeK%jo%Ne2bDfVj;i(;*)7J$6g)BtY9<i!_PI@HYZ^ %[kkK[hbds?-tl%f_:_lgeXGnA5*JtQ&0t<'f>q-F=0-.J7Kj6)nmq9H>5(BWBc)jG%qIn*INl`TI/np<d'%:lf__o"[jOsqiWUa"1hK+"bA7`"/*+/6%?F$n,^rGfc?.&c\iFICkTtQeBgiR?_9g/G9:N$lKMdnpil^^p==U5)5?7BRiM0l?b78K"H]c%)GF^dR<4\tM"qfhWcKHcJHPH[i7a!>hUP<4<@19*b(^]?:KTZ+P?\/GE`[QMki%nfAV?A6l+(g(t$O`\-2pXCkcU 4p]AY;-+khk6PoZ>lUDbnGJm2``G<h@p$t+39jh;9h+?^4%B=VJ<Y3<</0$i9Fn,H>7^'I(_B0^ok/>K!iIe:rE"5UGl1c-;O@Z)ctM#Lft\65Yh<@c#js.!]J"c)jQn\GBaetQ[0WIGn$P(Y6;&:*QW38ffW4DA.Ah?;#-mJ)gi1YT@!fA?7`]Cq>[87HL)rgZ0hYj\<Nm$;h7A)M#PS?$Iq!oSjVCqpaS#WIi(J5=A^c*mX)/#S=%UI-LG!pl -(!pWW2#XiqffEASLdN,(Y*]FR36OZ[EIcY<q%S\?dC-]"I.,bf+rdB)RmB%9I7q8>/q+_t$%+.E7=XB`.PGg7hs7NiZm2`p)PM'D]*e"Y]@-a/7+)DAH[KJ%1?rGgE-G^B1EKj&'CE>-?`mdXs#"\b,P3LmFqOP^d7C:d,4OT2ZpAfBt*^]h"+Q/:8e.3AeW_9;4.fDW@]!!^!tIss`*le='i?_4.F=/L'N3<Kijr1"d' AO7(I#0NIjW]*O-P(R25<&`.7+qm^kf4tpUIJ[rIn F?k"]9mF`""k)%Nn2-+#Xb**5@om2 cV$KVc((.,&N(Sq081q$cI]"U23aRXeOOa7/KcCs3;IXj)1jYF?AG1\YEL=Det;,8Hi\AmQn`c1O&acs=]*0'DMfdA&s4DUl&qt$a6G*/B?'-_]%Jc%!gW-.@be4R?k[M\ji] 8$srTOm'U!jP;W<$pXL81bm5Vfme26?m3as_4?M/l6>(B[d$aQkA%4%+SF4Jr!AHRTWkLNlr+)_H',e:6sEWnF1YqAiDGt?(5Kgo?&aP/t"ZkJgf6CJ)&ER&^44_dnjZ"> @`1L<3f,*t5Us(Pb>bKLBA[*n:H5MA ;V='WQ@[iBiPFaWcj"C\=/RnlUoJ-HCTgEt>F,l.*f92ArUma2 3m5oT4%N^BS$=$_KW/pP;bL6E1lDUPM6$F8OOcI7I?.d>*E35",<tIg/JU%C/T!sWa4:;ohiZ0,mXUjpC9@b?TJpJO>9\>4R4>^8i=/H@%_*iXi!@Rf\akh(dl+#rsRJG]H)B5"+QEC[1ci,I8f`(QY+>Ws..DmH+/BDV@9PTTA5!?nKhVgAF?['JprQQEC4^@16rgRqELddHHoSl $:X3HCrr Sgi!AOG#TNg&*?r^o*Ms@< Ooi]j28T)^C=II-tdag0=:oQn&>)E-d;+mVrWM*mH1d%m@Jk<*'F$I@KJ>.:25Yh73gOQ!2?<AM\d+TY?PA26qtE$5<8lpqreQIpk1R2EAq=?+?P@?2qkfTPq^J[cJ+S],:AU*kW6A.IY?s8sQjTo2^_7m7llAi&:rrl+M,bKVM#J%RDlo;I^MZ^Ab[HS&)'JTm]U71fW=;!e<W%9P=#/#_]NRY@C)&W%s^4t,*rFtop.4\I&$/NK96VXVJ?aFY'A$!<$f>:O?2a=/(G#)\X#_rg35abm8rBj8K&OF7$QKH0YCp[D*ROI8F^$\"e[:rFN2J;W0a"-Zqa?;(Z1CU5;OdaHIULE$`^O^m=A5t &Q'\"0U#i\(EL,j)oGOKmU^b>\Td=.mn=9\EcLH`N9&jWAcsOE2!HEkag7:LefbK;MkAA_!<e:7:N!-T?ORM)mY!*^$!)t'(_,Hr$AIgU0@3EJ-3%hrNtq]Wf`p544k*WPMq#XB[N7] V)4ej[Bip(X(gJ?=`ArpfY&OK<?(6?UlD3jR ;,-M ?a*#>h?iAWBN^Di_6R[>0n@[ FHg<_A_-&l:HNP!A_j $<r<JL[H9]&IC>"]s`Q'*7dRl'd%F\B<N*3c%8>&P.%Q?L>q)\]B+ce )qT\KRgNNHQ#o!-e"X/S=(I2bDE3)FV&4:fKY:?&9;nS!RALA>q^\FBY'-4[>lQ,?]#3/8F3.8;J/FG>$0,mJ3dJ&hi$,n]iE5P?Il*"mr3FQ Po-=<)id_<r5!A@AgD3NF$+sHqgUoHj55Gfr2rGhVSA\Q9[P)2f]911O_5)*cYcY\KNM]V_YACfZ1$!tRADrAWc>X)e/ZF!)qCA:#0<M]`/ h33#GTP%#3X4l@jE\SX>Hlh9)R0L$P1O3s(O5XjCK +$QRLM&Lf#\D[tJhQ0g2%.Et.1EhW-I$@8PA7ElQ<D`F]FTQ^0lC^&)_qn$R2tCd_-pY#7B#0d-h?2mB*WV ?pD%.">FTX4 @Z+$[0ER'AX.T0A&m[J%F=lqa,sP]_2,KG6J;AN,EpcbjNpAM`HP,F2W%@,X(/9s7A1.haE4Z#FV(Ut ;DHrtNPr;p_V(@9<`YlTF2\`U9Q_82c#!(]T;r0&= kat71d";K$:+LnaWq))=ON$KV:rIda\(@Anf_Z/I:>&-k:i$jn-^O4!j#NfEsGh[#"Vq%5 qn3s3+)b(^.Xd07Qd$dL61bR(%V$D!s<dqo86T"f66 c'q^/lJ[1/"o:$pLILA*rA$G9R'#gY[OJB=(3\HJlA1hMdPS-[(h!9)dbDp/MOl,_:ebkl+V@NbsX\D%6-_dp3-Fn+k-,P+SG "kA-h3C;<Z\/ae2k1Rm1?g/$NDZ`Of/3(V].(.^j6V>Acrh"JG'FK&r,d%[thtZ1Q&MgV 5Aa2n6jV+Mp"?& "i8h+dmKbo@<'k.<mG16:-qL]OlOU7ICRT)""d$TBd*&4jfgFUV";gGKRK,dNB_GL-JneUoW`*#EpEVi5."M\2O_<OLAMV@9+C&VDX0Yh!*niX1@0Sfdf4;oIL<HYP#!#"?$mn4P>trdH3P('@$-kJJrI7^.*$"Xl'Z/C#eQ_7@8dEmsQ\L<(8lqhf8OlRSni=T$@'FgGqBD=Xo"m^O8bJANBdn2$78Kd)Tmn.Gm.]f'S4-XCO >b i@K#>bL!a gme-G(e%-kbhB*SGXF(&bkF4M5[B 2ksLC[]j=BIm_C^n5oMk7>mXr><^?YRqJ-88)nH.lYeBA(TlT.Xsf%bM&i[iAqhD2nk#JkbTS.Bm tnE:?h, HONo<Z.<h2K^2a)Q>E?+(+t'q29[5Gg7D*0"EgODHeaD'[O#SDbpNbO%h#Z6&7*0AW3*9%gZMk8C,_#4R*V5Z!5Aa``/PAcpnIc7)q3NakD44nF6.r\P(rB<cbE0XDEKF=G;ok@o@'+]4q +-[s%"?!t9p`A(/YO'["]$NZ9R6kOZZ0r>!`cQ#$>PE6rn,Q'jq2Z$.t@clQH/q)K@IjIV?Aa%+.qQ^o`6+`NT-Ac./4;LQ!"HJ&@)]4kS-dVEthjcMWCM[?Uj2l5`!(la4LYpAt120S[F,$+i]MY0q[j!bOcpABT<*A"Ge#%>>">l>J!E=#_#pd73b\J&81(+-=b0;ofqW#DAeENO26b=Bte<=Q:LbC/W4L'NOJi*]kC(<1A<.ne;_k2K'(KA!CN5IYW'_f>XmZ3J5E+YHf><U.Ie0TJ'A'9gpT\k79EXXKF8b0ZVM CHlQ%oK2^ZtaOQUMLc&hKAA8A3']1)ZTEOZ<o=W$t1q14YPAlP7>66pe(+W%MeTFtGO2C^kjd;c[td7:f"JErc^WWW9P<GpOJ+8?4&i,+SfH/_G4gqie$fM06`*M;nVL`BQOO=mGet9)$`o/]'eRnbqEgs+ee;b'JNQ1'rRh9F]?,`.?M]s7TbZ.-7X=gI^Jq[V;aDnAa+XZS%+X?sXr BK,.G8`7d<p28WBnU2:ph>8X"EGNb`\P!3@kc`]ThN AYGM_6jlqXqj8RaH`BpnJFO2G;^ _A$Q0Ol#6 m4hSdOQJMfg_"j>o5Z$7gnSf%i:A=s5P`M/6*>oZ72@;0\\O\NI!bo<H>0IG`/1l0FW/<@lnX6#\BVl'nb\s.l4/KP60orniFN!MnRO^2`l'KZHHne*0:lA(Ha<*Lq3,M'>&fo5';oqXZl.tbHU-`O(sJrsD\3KA^,LhM!:=YmKqDRCN^&^:L_#H2SUS+n0[(\SE?qGOYE\CV[7UEIk<i6-*F` :&3X4r!O5&F1#Lb(A ,iOq,bM;= KZm*4\8A+^g,KTNo7LM!.<5FW/IbH/+%m'bq;5@GB""IAA97Jt_VT/K;9EA^t4rt[;0^.88>jR)bPsA=$%P:0jo%B67\S>F'D*Y(onLJi''3pJpDW^$Pd4\e='d[lCfj5m"ncOQ;FIGS+"*#kB#*.@ tW\Z&!rZ/116]lhp23o,2?=qpc"]3#8>$/QXtslaYR2e^A%NGOS6?^h"1-9AS%H[/tUH9NF)0cKjLAl?WT85G:_\%28?)cM#J)@i0ajWF8h#f!%9d68&O2;LHS`G5&8hUra(Edco^\Af_fNcgaoXaLH)b Y9DI[]_8B`=F*8"H&*)hD;]5O<XF'lZRd:;TKHWGK<QEmb fq?t;J#0M32#G:5/%Eq1hD97-%5JN>!DI?]VPR+`VE/.L[QFc._d!kJD;5.;pG^`7\?O(tsh$nn62%X>5h2j B1*\can[?.t5>:OElXG]o]BE2ni.m4GkL,#AM5(=5h'o5P9n sZJ))QU/]T!3ngkVGW2:Y\\=A2A]VQ'$-g]taXA8jY6@8c"He4j4ai [b*5G^>bRXBCo!^f!8c54&.I R!a`b C(<=.`Lhssq:nHF4m8`5BU>Wf(Fq/AnO:BgHbAXd4S@TKWFscj3@(8DA fCt3Ap7Af=]JYGcIC$k[#,%/jE+X8 f7<$!kZpZ'sT53W@@oTiKOi*9Rsr1Y-JI;>BOIqY]S34A:*s-hhkQaL3UCsK7eGVcodIqGB<O*0@*(fgmF@A<)Z2fDN,t82a7aMX ^,o//oZd$Z&ZW9A;r^5`ZVRbd:#t[G@>`P6\(M$9>q$OYtD-_`,lF84SFOAWdEcsW8p1fn6\UUoi(3iXNt[M-7'ZDh*ij_rhO3dr_V*E/3[iGGl:G%9 DdO%+[L):QVF%E9oo6_+j_o=@hg9c;nGt;7pWCA5OSEb)beNGrl7Go*:Ab9/La (Vc,CHTp -ed\QeI-L%^$'Vp]YT"Ce[HsM3"7?T#e,8Gj". e06qYPms`_'mp:AIgealhh1Z7$o5sD[o+^XjmC5-kaX]kGZC,0Lo3S!dg56eJ$*G#U+k=. <3Y149a=1@ _Q8R!DPMU^/Z-WKoDM0@!E5@Ja+&)`I]-H$3-@*_tMdI7;A!Do'78BOZ#9RXOGj0Hhq[#^m4&75kF tr&mo6OD,#G (Db4"\e0hJfAj!I#aecb4UEfl>.a9tA'T&O5X]j]I=ia3HB0158N'.%h"6j6Ip/g,nke$",.('-%UQYjCQ'etA(]lGP!Cr0aFO1GBX\F2;Y<n_-XTO:(bsl$bs2]eT5QZ0k3:cQ0HF.0c.mG0-$L4B6[SQDGaO0n$ed$_9c_"7%E#qms2S3=%BP+AI3rA=Ugt!&%=BlB!Q8rl4(p.W;^ABkk.(+%3Bf!AF_P L1iF<&gFYhbO-0H@Kt$S8KQs(YLVFF]Dpe%ljBO'#oY%Lt<M(0m??4F99Ekc"s.tc=OtYXP"Y+0e381+5=h=e9QG,J(QV2?1`h/>n?j ?DK"]kVYLb%\1XZab0n:7\mt1sHdf.pUOS_)#B+lat?3L:.T."\JbMJ,EPN^2 6d+31P,TJ:\TMRa6)*]lT6iG=B/W9l1)MmQP+oBH<O"KFZeR,sK"gFfCD9&Ae_S>&&"Qcq4Ak+f$jphpbGUc\f[UZ@RXh7[G?O0eGJ AC=[ot6X5ls!ST!+^:`01dKna?8=_V0s#Lro4'bgM52UR1)!ACO4Vf>4'R:r=K-=6Y^j"RFjjL_R ij?@tpa(EQ%n5.B&bCY]];Qr4P;LHZSm2b)M?:0rb!f/C457tRmAq1Sg\=GtkG;saf9Ag[AS*qF:FYp7$rm;;ksPf3Re9egW>eLT_V4L(a<\LAGjmkD1<FX&5DEpmtU59b]1M32#J(:fCoWI&!AfUgghsnTb2m_.G.C68?*,PF#cd#^hO)nA@Wj>(so:)mCI\4QYXoXN9d_8R>+@& tGbj*f,FC>+F`'\Ep`J1Wcj*3N8#nm;c1=qIi<N<!(`%AsA)Y'-NAOhgnpKXB W-3d'RB?\/T?B8Oe :73r&Ac.h g!s8f!7H@)KAN'.@cs01Ac;r#,;l.%t6s@gW!&miGDTWS;OA3GF67]!7!4,;cpZN("8(`[GR*GQTOC(_)tr=j)Adh-W%\'4\LMU\e(W&5$4c'IM<- MUj\;1O=iHcA\9D:Xtd9^a#Ag:[m`deAaHbQ=QdLhAY;tK/J&LW Ld8W+GST@TGhh9c;0,&ks $TObV`+osdDbg_c<>9*#HMbtdk<A*<mEeoV=rb2Q#PtA,ANTN,=:#= Mo5M\;Eq:9lHi>J!q4Q+k?VIQ(NW&nU]DEA&8pMTVq@6Orq;NQ[h6q=)?AEoHTEc<DsXBMqqARD&9O!9EY<7qST[bGk]F@A0&-Z*KWTI4ip@cRr.SW/)A8/'3=K^ZU:EJ1q@.O+p_JCQ+7s\eYra8^CCFs5Ebd+Jas^Ga0H*S"X.:2@XT)8jHT2qP5Q>QN?DYD%F8N=7F75UsA=^DL(* Y:odI+^'3"c`OK.;G`c[8;?c2[9bUmA37!/EEfNIQB*A"1#<sQJ*[a0GBV=FH9VN'tD5?>Y"3_._Y/'Ug&C_`&5V'')6[t.4n\<b+X-a[rH8Ci^:E5a3b XkAjD]&HWWVS-8/.pNM/n+-AMj6=1P>+>[qn #=A66c3'"a?_'R\QjPd\-f?c 1ga%M`^3;c+4RUe+8J]Qc^c,Ea6qR:1N_@#i+BgPD^QC4$@[7'<8Xi8^F\gEH7_,mHW?ef.$QcN6:C/?-W:]`RDCKN`d8GV@@R*k=Eh Pj1@94h%n4D#m<QdD?a5a@ ,Ws#A8G\6AAY4.Asj(l/\<b<NaQ[%F-/%InEjS6E]gVdTLjBEAS:mb?H"$l1XTJ<(d1?L&64B[RAA`>A8Rt0O<(l7;R4(sg)EZH?!/(iS@WX`.fro5+$Bg07]NU^+S7&3Jik'IOK_ZfeGma;rK#$ZF-iPa5+d2LMWJR504_EW'/!&[&so,'GJ]NJLb2kEp'S87"_VCmX<USO8M4!6AQj>sKc8&pDg399c8Zcqo+(^9VV\-4QE'79ir/;2eI#HTb3i8nXX9po&?=i+75Cg$d8QYB"qAB0RUGUdZjq)EC)99>ednIT+rG2P5>/"l<$^#62@X.OP0<\l&t<i/aQAn2-K*bJ"JP1SB\44d,77@<FL85Nt_B8$\B#DQEni@^c_nX^jGZL]4W*WHcacrkEsZ3<0jWE9!JWMA:@4/B+sE_Mj O>K2fqSko[-G5+WXG/4i,lt3m7j*gp-Fqg,2;DQAA17Qs\*:UZgH@MD$7.Yg+jAnA,_E$[ZrA(SbGGRn$P[ Pn[$Ak]Kf1tm&e"7\3ZgYWh+Dp4r<`'ha;]^34 ^PTd8$Fd[_r#L*tL2S(O/TG34Te\7Kh%WSk`CocYt@2tI<ZU^"0 [J`;l!g;B9"jAtnG6gqjSh89#2Y^!DA8(lgp+EboS8!Q%)UHU)BW+!XniJb_gjI7jZnqj>&0YIVoa@#:@iq#5"gL79n$[Y7Esp?b-3Z+QjrVJ1i<LG]*UenM8`='sdi9B!)+^Zkbb,(R.+!H31&=XQ[/X[)oF2?GrLV\hl!`?Ack@P0fp=kL3o[g]__F-]<8Mp(2'f&YpA#9S3\ibKX"9W.,&RM@'k53k/I[M;?T1<^2E\K4tkf.:LE=*,0>B&m5p[nZO&j\7BHo@k(,;`>b@A]b)Y:*C*%g/ab=IG/^&W`7eG?"X>\"D':(p2`D>QANkSke_V6MeJ3X4&gB,fes+mGORj3NApg34f0\+L:%JPm\PA=;Gbh^D\;[RM9rV/!pB$qNAA9sno2"bCM\QRA.MZc4&Q`?^OVQ 9'DLP-S,'U3la.pjBK1\g5Z)i>)S33M& T52iAlVo0`A76jFEimi&aafI7>pOU8]_SroKVeW. ,lM]!(:Zf1=V2%@/"ZPF:XF8TXDtAC'&rc<GitAK!RO@EM33MoBTP3G%7U9Mab@8.ZF@1/9(&S,!8q1at=5*C2&57I?phjEH scF`K/(=2raBP`AK,!0%BlY1d0L$W)+mc+6,OtL?(t&qr)pLS9b]9ECFm!KZS(V*oJo:g8_X-rhI[p.A$OT$#D]\PC6G<44 +5<rdIKBI(.d_M8/`;3,m0.!V*,q+WqU8pBL,>%9T':;oLIa<&P(D$MF8KDsKMAGig]UmRaIbOn<YbsU=Di9XooN02J'B#YW/BU[J9%WD]X#8R"a#%Ffon0$9<a)QBid@:t0_Pd.EON7:i"'/%pEf#AKsrZa"F[De,F[#fSZacHt3BZj]))[jm%coClL*)lTOGrD)@>P?9.Yid]s6::3`e4[H*l0Eg)\At:J#o38<4!>Jb2/QQN<H2`Fgh65@1n<E5=?[e(P4"qIhU)C!JS$a(1qN9q2TYBkh(a2B[)15mFb)Y#dN^B[.^tZ(+XIBiCqOaf"k^hfCdt*[%O$HU+9*l+mG@a]TDBHWVZIb.HE%:KCUkgf;0,#WH+-E2ljPK85OPnd!<25`AK?5[p>E*^9An:I%-bm,)Ar'i?0,So/k-G)S_(M)sh></2S(%ra7cA!&,Y6_n-N:56nsW#Hq5V[9*BXWGM2qr3QR;W>TqJH:_2T9n^P\A>g)[Q:`L 9X4[k.#X424]_oHPg.faGtb,"!s8\ PqGBae+V9R42d9qQ$#GC?>fTUd8KG!VIAiV$MWr$aMAf>,e<2jfgkB=i@\;CD$Oro^2B=FN M^o+ n8@07?E!`ebB^@BWN1?IR];O_f(sPdLnd]6n;5"7?n>2I[N2L?69OH.>.iZq6&`;^iTaCK !?Ai@S.1%n(A2\$;/fJ!6P0[YL8XT0@:Q:i]C*9E[-S,t=Jqchq:UW[AKFq%A6I1R(F0,'DT3UZe5PbG*?FHaRoBd[MNja0sN@4@X2_T_Sd.^> 8Z]A(dD>(5K54HM5@h"CK:`F/4='/0+bgQKc >Vq]Ff.HK*Xm`Lg+`L7mk%1"32so5Nq2j6W8d%.QnNZP`t5eV, U3Jln$]5^5]^O4lT8@SgbpS"F)7'p?SYAjBSR Q`opb$BV`:"3bt>WM%_CT'(Ap3P>i_ C$rbf47bdK760,a3\&EdC_]d?:\Na$)_5XF;B:_ENnF&Ltd"XEF[&0JfAsID)k!?*21!rI&:Cp?/tkUh>:&:C6KAFqCRQe3h;nNtD$kAqj>4kJ#s@L'YCp-mRRZ[R^p^Z,BUq=6=`9+!)&5AoJEg*rWK]nnb@)'"/S)CsYO-<Aj-pAC+LR>X@5?dq.MF[PWEU5pt5F[]W[M#rZ\Isa%#;KeQ=4t[r%K)mh6b1o04L]N8jlEB-*F8gn5o$TcJ>T#%;1Q',oiXOQIi0Z_lm,Dh]&0e6+I3Qeb9O[YEX)VB*K\_1_t'N;nNc*$I_7'0l-_if0pYIRimXPt?ZGZIs<\>Vl4t]F!X4E&(rEEV<I'1!+9: S$Mg:/*p^'SN,W4_'-mm+F9b[pEa$Di1&jU/,n&I:H`\6"=!Fit"f+W^Z%s:b3-2D5,]aeD5%[a.=F50nZb^Rn$>o6Wp[Ei^=+r*q)(lWCFrUk 40p(TP#ATs//KMZLGDmD3G9nF]A>_E+*bfHq<nB]hO$KUAYS6%B-I:_]CN1PPN );>A.A_-X')92n<S]d^QJk4Wp7 0?YWF%382[T5>DI?cj^nTCXE+J]Jo\"$=Q`l-,.blk58Q3N<$X?RQdA5B6=B8pEDR6:KH,ppA=jJa+K@n6^bn$'$O/)Y>J?c$$I-d,#3j^]j80Wt41MWs\?WJE,;COD?4ms,oD.sIRQ9a\!i8t961pg^r4kF)6VXh%&Hl9b)q6K;`hc#H8^n2 )AkTmRhAMi3I"RWbVkaFcN=+%5FYH[*>XUn0/b8XsF!+f^5/0ZfClKWRFbo)M5tjDPecUD2m=''7eSmM/[mLm!r[f?JmZcrkg!Lh[1dUfN?dA@)F.J-9M)3$.Y20n8Zg`3!(UGd<GFWZ,OLk3V2A1'We#bKF&(.#]1H@&LS8c/[_#&paml4E7bisULq`>(MW(!#5ZTk2.M"2cSaNAOAUktY' nW2%P$'I>U\FeZ [N"$%gr1Uh=[6AGTHBICP3:\*l#_Y0k"Z+i)W#8i_:O a9$IBpl>:i(VYHQb=`r"6 _fW:gmJ[^6*`E9<gJ-2_6B#Zp_p.DK]LC%0K3col2g3_FWKZ9/R ge&+EMk </5p>21NAIAZO^#7'9Vb?oI&.\S7c%#^#opo9IXehk=\0$T0,G%e9#82k=g$S&G%6N#^S@rDA!+rrf1"bRe%AL (FOT^tDX"( `1?C:Ip4sIW(W%[>5Jh\UWaBn>X<mJt+@8EgG_lIbM+)O@NoiR)FB\fX=XC3_G FPq3:ECsU# 9on?r'd59J'^/>."Kn[=A.c7#a"C)<:kfN" 9JLLN_S@aRHtdj<[DVF"f*9?)do<>pD;1kP>]0Vi..`S`,5.>9fq^pL]A0`k3Vs6,]857=RYbq@!UHV7#9\,F6f[O8Rh5,X8b!*h[.&6o?BmZ#9/Z)=[Ff"EK@J`p.i7?7s%BA+n6$I\-VL0agqa7[42#t)+a<lkcQ,']@$RIUdcnnW%"l1oU3<4gNki&^=).I@U@3[aWLTn`'QA<_4$3VV\?9Za5kO_/U_>`/-F(Rs,.6$+6As/EQAETU`7_`*NQJaYlW38t<[FGQ,\S2*q!7mZ]E3a2[gBgS.p=<s2JStK"Aro<,?UZqPR$-1EOp_b.,kgN9:0qI$RfC)f]rJr]lPr`WZ,/IZYSCM,gTQIJHE8GX+[UUMLf_@FA=HEQ5W&>`(O20#3ZfCMTjW);J;1_>6$@ZdU &m[HUg>Q<tgQ_!)k_QE`[%.ZUB9]k>^^db"&rlbj?KDiifhg/ZZ_APqgXga]<I?-DH!WC33EhBEm:UqNh_a 9 3YZR`nlt3FRqXKC@5e-T8E)NmP/H)gSL%bdT^Ar6Wdlqbm,1;"d]hL]>(?jl%0\"OeGm?l*& ",ptA&]q;N[%KIrr&p_YC/BpJt>aANfsB" <=<80jfO3+pc`%iQ[G?YO6eP+]>d?nq"5,^/b+ZacXQa#(/!&"bCEbSqpD'3WPdblq$F-AJi5)2(B3>5`jF[9LDU@hh6=q_?L`R9H3&:TSj,hfhNA*J&%d2[eWol4`ZW^)Y0^!M8UM)Fcq<;610>oIQ6/7GKALd+o.:$:3kqk)Mot^Ne0654ciIqn%h+O@\$V9D+tt.B pB!1fVL;MUGE`s;(<\*ZK3'.?WPO;jH9K[/G&>P$8Z#-&E_i1Q(^(>e+;[-g0PD&.AIlFo?\RFs!T*Z?#W<d2h]oN@:2`R>7aB/.+4oOgQd@].*bW:=T.qJ3\j#%5^!N^a `[!tV*dojYTeUId.kI>%?8Q&5Gp#IL'^Tsct/5E\imT>p*oJL KO#5Dr>1.1mRS2eKJ_rZ2_cS+c>rs;kE3a<[K3[T*-%R^`@*W1e<i?XfV#qp'#7 <5n1(M8Fhh>L9&_&l#=3NW`+Y^]KVcg]ZqYG,l2Z,j.7,[02J^J]!oeoG-5:U23"5Od,da430\ZNXIHd.rJ*;jUt9d>(t*L^GPkX]ce Ya#NC7c#MGa)!7cN)j5LF%&X0?D@Jn%*/A"NAV$G#mI-+mj)#/^ecY`^!WKfRk[)Krjj1ARmUip]/P#qG4I9H!<]*fVBJ)k*dr3,gI*\'M_bb4C8`ip<-G_<?3qSr00rZ`%W`fA*7Nqg6m`". t] g2mdFdW]WAc9)4=#U/P>ngYq,YmqEj,$oYIi\#NF(>ZsEZ"JWrfdhTGDVP6tSH?`Z";]:gMo_QQYXA7I4Qg?Z#tE>?_t)*t](SE;r;J8cS3EP7.@3p'VJW<A)kt` t5"(Kq(5$9cM9(?7cZIbID&b=F%"\"=?E5&%5$i)AKY1&3IY3cQ@:\!:'BsHm)f`=W]7A(F+^glU afRa5_Q<KWr153#1Q[&B9g`J;O'7"?MJd-7]`)M/8$QBh\;e237ma/4!D9aN:FJL;SKAWAkDIt2IN!5'TFKVm?C_SA="(>gD(9.).N'LTH5eA(sfaM8)K'8QK2Y8*pNK9KN!%"6'@ho>PL,fHsD%eim[CThlG&SH>eTd-BUo]MC?D=gptat:;":Q(X;YG*5rU7Z<K*kAUA=/oY/qE%?ft`LdHnI-j// =(aqk\[K^ohBsC`$%LEs==T$M `F\]U[5WQVMA3oGd[p8l]AJ`m?-IoSR&JU\c\!&?,##nrQB:>HN&[9[!)eRGqnV#8A44nOnh(0Q#+G))c-nQl1Wm/]t4bfpO&A(p)H_8@!A_!rP+0#(8NNa\53QCFI<tk+AQG-.=cJ-#5RcTP>!Irc\#NmmKX;AX:haa'Xl)haG'N+(A@hWfd'QR(Xql,mX!#OA.-?k&Zl)HK5Lmf6&Kp!!d<Y\8W<][Q 2.K&b(7`4nmjl5ELj#PiZja&G-`!fXQ2q<VKb97D44;7i1bTe^JcPJ#;Yn[E>S[fh:rabYhCSl#c#B'F4ZZ-UZ\$5XJDf_X74K]nr>T+"jem!+*`s[Pq'$C$oc'/r=h,'6!O*=3.1m3.SPF4D]jS(X0#&@ZCo)[GG_?`oddGD 7s/7[bL2 fN#KQ:7i:B5(2q$;s=n#^1"c$,5G^6$`V!H?!I%/M.t5n;;?%rph(p0YP/[heg5E,:o3toP@=.OPOPUSnd%RH=7k[O&Pl6c&kYdi^%Yj?<BgZIA@34tffA;lIZ"1(r#Jo4`KG<nIp#A@^/9j)c7(?:@BOJNeI!&E=>"FEl-A>?0isP3KJ*=k$--I5Rr:EOJWo>1bA:n#($pV_7VoIs)GR2[p>C2C\p5A0X]o J?QjNBb$qIeSQL=@62^#QhfA*aYA%f'$XRl5l9gh_G,LRb7a7O1Zg_;r&A$tA\PK&B8sASCYObeOA=(FACKH3!`[DHfpf1\JQnEb_aOk@UbO%?'3-WfSV?b)DIcVD^I;eAU#9`ZH(rp!i.rf0tKF[aO9<,A8#or;^g50XfIG5;t:3<)i"gG9)7CQ5;7MLf>)nr9EY@kSD!Uis*c0/^Y[aIYBlKoX#sQTP4p2+]$ZA1;ZmF%b.aUTSi<"*+@A?G.\6d:EX2%=1PfD'oeF!UtZ^KJ"3JnSh]"s^8M4* ARL^S+oi.Z5-$j`6]%?H"gr;YNAr)-rNT!E6MgGkVN>8`9e#$ c#/`"FR02ME,e2)ber_C8^$#USH:EaV )pi;h=oT aW";R&&9B Q]P@K:!1(A&"G?]L4_c-j3lFVCCqRJo*<$3$!R56l<^*C;)1GBl.">LC2QnRi"AU.,%2o;E9>F.TW4rCOfo/.iH_\Fk'T9b3bR=T06("Y=C>A%7JNc(`.G":j!GCto[<hfC]9E!NOA@<GN1\fWZb[-o5W#!>aZnDR2LTk1C/,A$%Qna7/lFEjJ-dHFf6c3`2OQkYBi"9m"YZf+<l"qPc8%X0=#8ZIOkEN_EA-t\Z$)3bCh,A;eqX%i&0[iWm$n6Gpi&?]XPXZrMl14%H3+R"i#4Jea]3_dQ3 B1jsIVR(AR"r_r*T%l.b?%++-G4O5B%oGDg6 T/Vij GYeR,'#q3OgANWVsVdXRo'2Vqq!"(T3U>,Y%.&o*;H<*=r0- UT^ gp^c8J,5cgsUKleXTH^l?kDPC1 =*l,qpe@n>0enhaI!4A?OR6jb.ja:/ qrO(T;_9iTMME!F/]rOD0`%V.]BpcQfk]Po:)0kN;)d%.W>GCY/gjb,#Ce7'mCOW2FKb3Ea4ZJei%:a@^T`p>D9Q(;I?U;F7(Q!eV.$(O>l_q#olXJ!=B3m_N;0QB4^<nBB%N']-0si5Y[<U5:nKi8/BmThY,q/2!FE3hAA&_F^'101\sILD*ogY]CoKW]N*8j52&!F9'QEg@h[ d^\r*(rOm%+];!#)Y996'*PW3tq[A.:%=r705f?6a(Uj<prOQtaSNINUIK,7(;nXIp9c$g@(ID,N9THl6A[Sf!QXI6nF2A"ol3?5Z-X-8j/3gcm<mbPr3Q0Y&_R;j`XdNtL1Fj2l5mlcS6rf(IV=/dS?\\(fgoEfL&(9Y#*<F $K>pjrmRp-4.#=#)Xm382Yi&8jA[-a!(S2Mi6VZ+>Q lFe ^h6P)_N+0nsbb9Yk7R+FI(WZE8\nN-.eT;105'(^QCe<b_"eSJ^es-BDt@O!S"QR#o"NPm^&nM<: SpI.=ksN300qBAUQCV!Yqbcs8AJ%C\(dN\YEI8,h0OX` ,#:T#flVIA';T.I+cCrOb7IN8;LHLkH`)ri:t7WR>_E$J4e\/8ThAI:CU`R'&>HPL/pt(n"Qd\A.5G3r_>th%lS_^sk6H].jfmTNpsJ=",8$"TStbUY#&8Gc-q,Xh<gse$deq<a]F6FMYG2g6W`_oD9-%Ne;0VnpJaM\f-/obn`34jB1&Rd5sbl`6<:D[.A0[DStLA=[F9.;+ 7,48i!56#br/X'eOE3^)cJp$0#qWI36pjUq\Rm+Lq,P_H*[4Fg7lb_(8VYlaIn!Sf$/VBg(WFALPf=#,PpMT3< i2af/k]$=%[/W1#(dh+/Oj'PQjAU!4H*:KO1_Z\?;QL;'N4 "k-Ee>4]h.p4YZZ@>hm8^_tZ[@AK_h$Xn>47//PMT@Y!EO=m49=?CO_;(2+nS`3AgXf&][c_"$N&BUpnj+SFhTQ1a<dhW Y_NaA+CH ZWoE%e-%'3Vl!rZ"#_g>CXsZt&WFpNl66A&2V-Qt(&&""=IfljF@"'&]Peg$ik5L%TKo)_^7m=H37bb2(pOX-APf_IlRmiAE#c8*Z4MI.bJ1:``C@pSH):W8Cdo<o\co+>SE#mbo9G5c5"b!VC9IZ\6GqgGtAAlS#S#U6"kE@+$`P3YC$n>J52S5t5P\*Vt=Woj.->>WOg`d8:iidhR\F`Th[l?;m<,OAag'DY_DmXi-asq^VA6RW=lpHj*"3;J_dN:(AZ>CB<a*WrK"bUc$=EE@^/7k+o+L+.'jffPTD4B5e"^+Nb#tr:\Uj?a4(S&?O=l/lK$`%Hq`7cNh*7Pf;g]5.78]P_MN`PfVk'KWUL%HSgp@(Z^@#;nlJMXpSD56I^c0'V!+Mdi,pmK]L'D[orM<s,bTB.aEia>gWC&2tqrf]/*jl%:Y&MtK@?>\Saf.>:cmp(-\n9K>#5DCA$!_+k4kJN'Th]3Qq!dU2Wd!=QlT&n@^eBd#$`/rgc1`IYFjP1KAh7!RG2-%I\t"ECc`n6t5`sCgjHk/rMA5])U\7hMGh<(UAc0RP1M*VaqH9A;2XY.s^s8-KeAH#ipk+5@U*DF4`#+h"*,>3`6[cWB?cGR-TehldI1#E^88TCKd\m7&IQ=?!Tb;DM_$RI/&8;Sc%m: V4o;3[48$>5d0R\Wem;+US0E)+`G<2=]Zb*L$`W0[^dN^N1jQAWEcA$)L1sM 4YIaGB>9<s6n'rUAE=kM?OEof]"ng9Dt7m-b9LbR;Wj*a=^-Z]Z2OB\Uq)qS0%AUeJ,(?aK6i1$"RdFh61VO5*ZX/0,Js(jo'&ITRgP7nl/6>,e+4m4C1_[g5[s-S_5#L2f-ZkCFE@J"l?s1(&*":A-X'Ki@B*Z?AFdY5jlk5OaT,I^aTQd^V]iH2P9GY":ph=P4oLi-)3P&[LS3"cA.85a Vfbl5VA`#[(UDKh[fn8+MkV&B?]`6D3o#JZLa9Sfh0kp%Z6>$MMN.!ARk$Q3og AXd"CNCM)&)669T76A'*lB&A".N#Y0gsJ A3sc #/cL"&a[dC;S9$.C8R\[Tg`Rk)nmt @AD6>sk5+6-8V=]F"Y5`Z-^L>(2Q0_ pcig6GKqho0/5dZG>6.U__ S6,!L) sp8eYZ;<Dd#SYY\mmYt1BHO7-B=q>F`K7GK-]ViPKqkIrhM.AT%3H%eH 'mqa<lgTX Xii$IC"#_@t*KGro(4j;9"V.`tPX%3"#gt/73ta]@>4bh>\.3P)Cis(/;W<%LVXeQlQ5lO'31IB_&Ue0`<AdoC&s<bhdA4$^;-4WD8.=RCBq%OQ%p[d64UT^^9`9.ZYg Ak.\8oR6Sba!rLVn3'C@/AHHE90#GsphJ9Prh$8.%21jTjhN&l\#8G[!.3C4 ]d4J^PTVJMm4bpl*3PCkskAktVO1(8&!h>#KA;A*1oGdKf268<lLEFP"9K<!CA\qo 50!FH[;MPjtiG^N>licsVtcpU,5<#jnr*O`Yl_fTA<gX+?SqA\1<^"&9mb;q?$fn/tS#@<9nPp#b3;=]OGb=Set9!&A/,e1?C7&XNr4Od,OAV_;mRNEAgcjr(00X]p*n19:@inqWO3Z:3Oa#_+l0I@`J$br@?6E^]m'!$Fm^BF=CDlnc>aMrlPDU ;d JH4g1]Hqan Y*"qWsiA[0&h+6EY .D]4&<d$ t5-T:-@/Y6!A]7;@_#k-%]A`VO`h1gDR A!i>e#eCRCSsC8Yg?gRP9rhdg:@g.H!X2Ab RNKBsQ=>mde.t3)7&m#DbLG]qkm1Gr_tAc["br-7-,3#r];%W$ 3m>>K%JgT;,!@t`IH?]R9]CEq*k)At7Q9<@nKbX[8m!:OB)BWP#<_AAO89sON[g=LMBk3](F]A8\RYt[VmMs#,iQ[)eC6JA8r""")gW?Jq#5!AJf7nAa)R,3e2Q?cA`nFp"M^)kO[))qS6lq#%<8%%,N7A`#Lk= >kAaE``=S,r"EQN\3JMMR)bF/8!Wf.O%A'MqIg>EC$s`6%: >3]pHd[`hZ ,,j#dH1>OWPkL6'^HNb).YhY16B5&s:!k_,"&%A:!ZRpNfHVTO3q<\QNAt](F%K,B03a,MYh`k<ba]7R.,pOCE-_j.Y].?Sg%L#m_q3*(AC\rU$!1:CoYgAcF96VFGlK$:Vpn^mC0'Fj\/'HY6-@,8Z[c=p$dsqd6l2\Rj;3cbM$5][jhgrTQ,e90d_)l"EA[`5r1P#AXjeanD\%\&he1e!J&iii?Eh8'FoZ6[djVAi&P+c_4RZN"'SoH6&kb>^jreYh&?NCqF_H8\99 tWpjJJZQVqS?p.!-:NrIC7*[7g`dqa.M[W6i<c,VaV)Q 8'[>#8`I80ie6GGY+FWfAp6Oep^\=#=B#.rA8:X/=d` rP)t43i,s^bKkPBS4G?_Z]Vhb=HA)+7E0M ^V,&^`c'M&kS(r6b#ft(F*@rYg5Zb%4.gih[+,r '_V)d07/8(d7Algo)GEhW>.g#jhJ\`C\Z,Hn7k(41`o:. `9 pHBRGA0q/%<_+43<Q*U?Dj$:tMX)Y3SJ-U^\X- R[^_0H2hIR/T;-%@2PtM]c\??A1D^F&#`H'&*00MjMX>_2)lB9gjFH+OLjVa&:GrqR"$_'m0/GYKA`FPio<Z-#+1qf1/2YLSUW.:L<+ti7k^j(tVY131(Yf !Vm.&^rl"=OR-`hA-jlogkW]M.k?U<d_I@IXeR[c>D-2KlH`fk"Zh,@sOG30,e]#k\4a)47S:%)lhNd2-Olmb,r)hWDW^pq6t3](2('jj8V0oDRe)-r/[mfAHol)'>"R/5U"5;5lW>1RDc5TB7`gR<(%jmgVCl+.dLpmsb-t  I^&@.lA(99NA=eL'j[ZS5iQ7(27&-JjCTlHt&<4r;OorA+Qr/1-3=jc'g.*$`Ap>3)O'_M"h6Q2?ghgsPrJXRbA8T._&_)04!0k`ls3/]AH)Iq>s&aGK7fU55GEQLD$J9'W3'.`i2=]F7q)8e<UP`RDGKG>tEl!B+M5_Yo1bN-B6$79"0KM]CsnY6;cqeiHNdO.9J"BI[;MCo>R!rDX7T;*9[_ \s&=*p7e7>4L'L>knbW(n9K 45(T_<mYo`7FDa&cSJ.:\o<&%^t@OtRqnY^lKUEE\_]BSZQL_4;Gb^#C>G[$_4k3Y^8Yof)550FJ9,^6 #AXiQ/tekn]OA3Q_IG\;nbP^-@!EQP6n!h]`-AV*6Z8kUQ!<fBR-T"csCmN,b;8O/mpeIN-l.AaQ[Tc9X^.i;$If4_FV.) ``9,lNI\Mj omK.YB#j D2SjfaaW`?TKi+CY0dOpn^##5oW3O=YN')QI-cBXb-5EO+Y.^,;9nr2n+;or lepUg0'-Io+N*$1^[saO$<<n]Yo13^k`j+/UZ_gorfHm!tAmWiO(<]OcSQ1.$:F`bF&A8;4@MFKJe>g&dL"\@C&EP cN/>O<ElY c`Uk Zj4G]5b?+KZZr*m* Zl.pd= MS3JH!rOC%E(JG1DS$U&'YWbGn!^CL$SAd51KF(kL'ojFXsM%Ck=AGIA5J5>B#A<J7=\Oob*n38>dfA["=OW]s::[WLCfiRqa(9;ldB[REY^Ep#//28eMZ4<W%Df*q*D5AM*-*Bc"9?fN67E<P"en76$U,,!fhW;<-;?UV"$Z(H?1m-n]Q\?dB61'\+lKA]TCZ9H:5pQ-6=Q$G4729/#!n[s<!oUB@0Tcra$e.Db@dAFh2Sg$3'Zlbmr_oC"o?]>Q<L6[m#o[[HDXS>T%'6ZfDBlE[KP.^V3ljM3A%=?,>+/-P83Mik2hsGoB.a 4dne AeO7i-mqXo g"LQb)4!G_ [e">4Rg[Yi('P*Km3K\_=1(4IinfR:<Y6adAG eir?6UOAd'Be_bM6""?H;QAN]Y6leN`6TX(I3f$::F/ra@fAjpA63Yc %2\3rJS8b;qsC@]c)UT'd!A:Ak!'\i*P1 25WDDb'D)b^:so`E4l=?8F"lpb2nAp+\eDT21''$m\&l#h\g+%"<dO'#.aVE>R0lr8lfk=94PLDH.IoSBf,;]#nK"3kb?Z6RY\s],LZi_"Sd@NAI_$GHNBECT-grSAOcL@WX1,'FDeT2XL8OK;d-,L)lP,3\ngKVG[Riea`tK2rist,D&OfRZFD#p9]8CqpYIPq*n)pUEMW- FEpiW;_(< <6To3Jb?RdV(@1j?r.$#2^>U)#AT]+t?=FcB/aO1h',8peaN!_qE'CM;aLTPF(<!_[8;'07l_`OI1?g,^]fb=;<k6KBS0f(.6e)<l3aR>pF"b'`kk[*G@%bJNKU<a]Ij([HC'lI<h\JcMPARB* JC>)=]#?FpeV#28^Ffb,1+mY6<8J4+=$M'!7 =_"1PP12";)Zt*MT!V#B7coB0lRHT]rLXEY+3t"-oq%`gV)1IEs7F?Y,67h%8@6,[H"ihY9+5:sHTNc/qo-esI"_nrmHUZ7Y$!Gi*k[.TFrKaagJ#.ZYc`IZDb@S;$R`T([%\otr(7'-!-8_P/?#1qX4e<^==3L3codji\,sAA\)"NR^]KX38CDA_ZRk9g/*Rgd'dIU'T:UREr*9C]bR^"e)&Y6nC(fr]"=0?QX:6ldPb8)\o\Hm7b`:k_PNBYO(itiV"o./S.s\Q0g<I;qQ>(!@%qKX:32LDk^S(t:MBCXA<j Pn'4tpQbgBeOX(V5?'WgC,7#Thr-n K1VU<VKjE,23!,G2tG0'?.c"#],,K'-9AgQ>6NN1<q%ViZMW\OAk;aF.egS6Y+(g1at!Z[?N.IlpD6"BG.!J'7?;l3>AsNU7_-)@(He/,ltg[<=IUe6,KP$1APhQDl*O&lpe@2At-@SYUb0%WYt6-,Hg!)>DV3BDO:9I()T/t. dja7JL;Zl3@ )K7@*esQl?.:8Mq"YW@DisKkf@T:jA+<\AaFYJm>1d%;m:('"A0aP`C?>D7 eN>JIfTEIAS1Q@B4kRn<Bc9h?'+#jYqrEWN+n[.?f0%cVj<WmFD?\!EC#[;6$  $h)H0WGIS=/j8r,LP1tY<2ns' GtS=GOG)8mBnXFbFbVn>\/`4JId3a&'^,\n0XGE*Zonfp$1?rO3LT3Xol:O`46kib+<\F,ilohHRS1?<X")J'<IhYe'ZH:\e;C]m`Mpn65`r8Xs=tj@;<b9a$c!0c]<^_MQfZi''P,M=50C:Ac*#s=5p3mga^t=nK':YT=rAacMX50lD2S*56F;[: _agqTtBLO?&D AH0/]S4O%E,jjpMKkObY.82n:PqAD[9+1UUkmA\;HZ>ElmM(#eNE(!'Ip;L3O"t'lr[VhZQkcDO\5*,0d]1PD/( <I#:X8K:;9^m_[jU_EBFF$;<lCN@PCl*S\Kll06=FajDN0PgBT6MDqLoHQ_SC^:A(VAK6;*EQ)5^8oHk\A!0%K3SmDf_##tRS^c"t.3J-nV.&]lcC/=Icq,7&/p52G]idg2/s@[O9##!X'F^dmJ^Y@DF5>mf bcoCVi2chgQ^I%J1Qa3I+[#k&b;Rd?PUo$Nj_:*[`pPNtob%3Xt!Vm],\`G<V`]QiS<!l_a%AQ?"5D9UaVZ><"[AAYl0n$k>dQ[o-SNbQ<qTEND[<a%4O[?J/G_!^0[VPXW 5Xt.QDD/UG=NOsr?`q[?4.)QT9K'J^ipt=ek!g-9>'ZU,<-T"<B])n:GE4I$!4rRGAm8V<.XQUsiHK $aYTl0@1W@5<a% !pa> Y8Zp15qL@=Ao[NY2M;rAJYMn)X8p;c7o6*ilL(`mXG:aH3KO oh1=t_*QZ8?L6Mrs^+U9h%O:b^WlA9QiiRi'nZipZ._VbMVI$4rBg(R5pG!DD$bn=2:!*HVUHE(4!TDZO(A$*knR\hoWjk8Gojroa..Sb]Md;t>Ri49_f%8q6(p0i1+7//+5<KJmp)80\_m[M.qmCl_st06T0YKfldg$4N =/ MQKIhpmN[\oqOdb[L$A#m6_^H^bC'+t;`cZ,QRm\L48e1KgoZO,i/O3i9$)];(;=8r.q;i_?PTmK+A!Zq J8%fdh8(m]L*6?2jT8j<%!O[("MA3hX=Fl>P0Y+lso[="9V?)#\'mBrihJ9`0NG[*'KjpP(<ApQPWZpcG>*Q9ofL^e3h*kb,B5YJ'M$#^P>&Y135]ci3aD"d&9P,"%5"_YUXpO"F83JU))9PJk=?tp(f0.AO7SO$K>B4AIa8IqNl'OYbY"jA;[7n%Gag_9W+egY.f8(k.h)q%LB@G$:#C1FA2XM0>TkgG$kF5[gPD#m&`je4[-'8PrCC"VL!)sf;7E5Kbh)r,&kJHlgEAS\-`bqlN]0Ya#ka2*Mi;K+@EArBZUIp.E>NBh(j`U<+-ntk>t-QmF`Y,jA*I__nA._k/S"U[ql^[Ctc>e=Rs:/oE7/i(6A8^c[i6'\tlQ.q[#DoBe[<BS(GRMR8(f)LTWWh9pAD`R+Mi80C2?APkYH"nA_1^+osK\_brdlsdSbEetG0E5$Irk(:m#r_7Eb&'e\l$TJ/lAh%a7(;h`=rHol<5aqhl:E,jHcpPoY9sE$\,?A%! e>ZHk$ Vf1W5e?g2f\6bK*SSYEZboDaLqNrBB8nX(sIU+*Ca+!K:&/f1_`Ym9rMWU.e,r/gpt;_4Pb!\tIW"m)f=T>UrS2+ErcW=!#LbbR3h<Cb(`3n(fOSX2!jTA!i9\K1K)AV]12k!!Hn2@8FoqfBK0)5kisTAbMb:P"^HogtX\4q!OeF^!G,c;boDYB/7$#cXUV,+0W*GjL[3o\#(:a?H'BqipVm1-sDj$=d>niPS#J>3i61;qWL.aVmT!a_qA:%LZNW7(]=F^p^D$$cELa&_e:AACH0D/b'BMaat?hrA+9tsc)66"5OsRr(ckAUFL=TgA_4Da")KA0@)1gp#c1d.P4-n*ng*.XG1f.=\-;(f]\s"sE#sfSX!gY,?]sAjAOs^V_&b4c^?i=?iDjp7p%^[O+jC$Nb@l9CstnbkrQAb?'tRRE!KJ?+TtQ26[&eU3KW(L7`L)O>8E-)GN4H6/X;Pg7A7j,$]&[?KLq1* o[o'mI<maVTI==r72C MRP./A-5V=0mV`^0+e;.h-&JPGLn&gch0'#@-?OKl[p[8G]8LRrOTC-+dA%3LenE$iss(cg?/[L*nH$A97h"WSt<an!'ZceZQ-ZB=bFs)KTFSCA^Mt^I88`i3hA<7L<!e@jfOZY`?nMO;D70[A=ngLid*=&UXO71R8<(81l.Z:Qkh0.RAf\+Tj4j2aEDJg?>\iP_m?ECe=AMh)Vd%?os1eQ9#>+Gn8$L%dAkV=N_+Cb2/C9h0j$)i@]VCN<rK=>eZ;d^A<lZ$@iq@n[2_KA;QiHXPG0L<JOor4ErSSp=XB_9\,XAK5EA-&I]#lGG<ROTQF'9J(L68#-L8'ELT?C_D2dEd_t-b"Js&9-%m2=85% 7N;AmZh]aip9CC;`bM^N75Xr'$e)+DG(,\%>,Q7:Z.?]#DV6q1SsmMT$pqN""p#`5HjbIH2^((E*dOp\UFAZVKkd2S?FM=n&[nHMJ]S2*aA%WFE7(e"tQ!0T()5T]?F[RQ\R?S[Ms8*-G<iaJA"UDtom+[I^K9p\9snIUt(PA[["d3DbTE4@3)7amp,$,W`Pl?A1]Sh':`%;BR+@bK>[fP!_J<6MbE&cY=$;1src9GdkKiJ+ZlR3m?M(;Fe:<_D`.;I HI !25$:BS-I<^1SPj)!NEmJccU1`0 >o-S!b7hZc+C(.=k(LI66g-"WP>Kpn^p`EY)T^HB?nA[UW[HM<RXbY2;"kK-9gH[_MbEW_ET;R!M"?U"p!.+[/c'e FDZ@is+!2tF%[p3igUjIqIh.#RiPns_JhaIE=Ei(T^OPad#52d 7*^8[8kZT MZVc7C'tl8jA=\.&8VQ;&[;n(8*2LDD$#P/YbPde;c3<sB1>D6&,qcNb;($:gJmLcLa;mR17pA0,I1lBj;sB4U>?t>'_sA 2<7&`HACF9IMJ?HlSCGbng-J[$dG+&ntD26WAINnS$ A]_Eo&;AJdci;W?kUBK JbHDU2=G5Ef#hnf1aTo\AsqX0nBCH'iF)sX*->7G?;;FSkT%]^U\is?>BNWMXGh\in!Ld=b0g6OS,41jpN93[OQa,1.*kNNV<H.sHba/A$1Pl^nr)9d42AO3AU#^V*5A5EJ1Cia$gp^DnSGt%=B[=en?!q\i&A6eiad`V>Yc`IMI?gX_3YZ;ZfF@+o>a^JZn+W6P;UN0U<.WdE4)=s.m6_%4fQD&t9@Q)9>F"O)3*oS An?632I[`68Gm$rdPAKMtHb:dU)R2DX#mmVB3GYt71=dDX.D,kLOnNd"EC9mP%S<fD#&5"$'r]5O"3c#bRaIGDtd%lb Lj?`fIQjJ,e+q\>9Ln0IA&)MMa C@1.a+:"J)A=>LimCYW(1t+9,4h\./VSQHRJt7f4UJFn:HY7bef%/5=-n=;=Ek$o[Q( .:-a,fQG5TE'dntYs7hClXj!)CQ20gEE,3B4^hFrCOL$;id=;lml.kg-]dX0[ZiJ?mZISK"L#H=4T^osPQU(P/T.AA/Nq=oh4%n:m#mK<t%):7?>M!D;QsN+1?+E^>iC(5$9-K?;J%^E3m.UIL6WZ>i[bY-sDtO+6_BDXm1tZ@%c<`&b,g 5XVjH+AdPTWB"+sp#^=hX^'NnQ;o;<7-c_>l]%:O@&2ei68IoJO0+h#Sh"'0C)^1=-qb>C)SQm?)ac!<MIS$K[R*=D&XI6BSA=U@&%Vn*4p`Md0OV`c\ Lf%qmJ#$I?5gs` ((o"]c6J,i:^!gAb+Q4rjk9;[SHo^"&d$@=<^N%e)!AZM\$n=V`_gg:.;k5R8*aOU$&&p/-Y-IPf:j,XtJ1:(HmD"_PfOU'Ao@g+M!s(G[f!<K!rfA\R20YtA!&B8d_ PqD8@I>5DHA\c4sNW@KQO]c_FBO^B>5B('FV0`?C36-&h=ap6 ;KHkY'28PtoM00:m_!:h5AK8<^)O@&27VPRr>s5L6CFB9ZssE(ZfTdeGPI$T;hX#ksB(D8OY[:7_8oD;` ld8QA#ON4+:oi(Q75g]Uh#'YfDJSR "nVWiP$q'>(R[-=Z8T#WI0rWo&k;0<$\9F]B8O5!baW)45APX0PTd4ST^J[F5moRCC0InB)/t7Qcq'tWL%5tX!]Q)E`fN38\8$hGDg5AA:)e9cU;qGf2AG'2Wfqk!!j.SV2EYn6a'_Ors;=[F^6D5B+M&9Oa3J>E-DAMA#[q4::0jp[l)h,:3Y*IVcb/"pqV(EjehdV:&\X&]'f@ffj4P;)'W Cf;_2-C0Ps_tJ$@*ZeV6)LfY[a2U.m6'VL YFAG-)?-D<`8!bYab.GE&AiTj?*V(hAsHaqNHUN&3_M%(Z3.@NB;%gfi0.aH,XVl8UTlG6gAlcZsgYM\7ZoEb+</?@ekq<l4'CTEAqKW`rIU1iJ]_hhm.8Rh$ah0@HqnkAG*R8Rod6s/Ve#ht!ak4RMo`k`8N*3:LnM/5lQs*/^aR"`fKSZsCYd7?#X"p*A?491oA#Ke6id0*NV`c_3lZ.21]AQqH;c+BcX!]XXfc^.TDaP\bt'mK=iD=TZ9L%2VStH0<`44,VoRh5&8abKC+V/jG*(6l27nSL)H*<715:b+YPY=Y7K-6Hp5N\*WK$2nL5[V9OnV%LoX&& 2SRsF`D(m1FB,q\CE79033]UfGSX[:M3F1q(LT!hjNATto:QQPe7Bm.6A0tBfSo^-@l27HS3n;":<K%d6i(5CDMihB`nr7,0DZo5t@?1>FW(OB+m&g8AR1<!tHRelLAP"?FRcatTtlCCTkWM6V3V:HK"l#ofVd]9F!:ga-R5#a]q 1(Ao$.i[9*X1M7_MM_gML^Y2ebP*9kt`<8TqqN@0VeW*8c60)(dJ=Zq#0J_^&4c,;NTBOb- .=D3BW3frn3i!-h&r=EA8*ts>BB`NdPmTd8FD?!9*NHZFQ(*Hq5kc,/oJ efAmpWGYtP+QHa#LqN ;bGd<F*nq\Co"7k!Fn?7'BG"MQQ11%T^ID'J20_0)@lH#bhK\#^df9*=9tWE+oeR$o&AqWe!ADKV%kn7RHUNS;sn:]J"K#]Bl[pmh@eT.1=k*pd2pRs*L5IKqbi9t+hA#DK96Q'fg1'fC.3*h_(j $7Q<`.<`'>UOep`3&Q*:NafN6@+-q)%l=Bh(AjZjaIsF!32;'aP31I';WtBo"_DEk<#?$54O4mOH6YhRTp\oUZ=JTEfDo9*H@I+/A`/H$)PL+EVM 3R4nR1^jOc!_^?`>8KBMT*]QFP4_r9a&M-A/MM%9&Vqm58C;IJPMR&!nXR,\6'D'mFfh(TN+.q#$=k><h8cRE@NgXi.L"X`OrKc4ApGa+ .1o$)nkM3qJN^ FHr\P=f5&kdd`Gg$i3GS@b/(2Jg7#5>T?5t9H?$nYX:@=DEFLVkgA:'j<go`s].(N0lDA-f0Q.^:oE6"^!H2()\A"<9*0W$*7o+U44n,X[Z g2\E,e[d6DV/;`@D`FT&&,":snlJ,Q+3siD&Yp>M,?dGG!AIKHp"$0!KA%2%!d;(#\TG>ULXZ]'24H?Kq-hK%Ee]18#S$nTE*Q$m;[-:@7GI]r3$#bNg26YaDRCdb1H&G[]@f@&!#%]7o&J:RpN"J:Pt5M:2;Af00/b"F.7!?_r6gHYI-&&l*42`PqXHAO&cK1S q-A.dej%g2r_N6UPcZAj'/Q)iMYQoWA!63at](rR8BrAmc@5 g>XK5U;H8nY)jn;jRV$p.%cAZoJdZb0.U:dba+h,[E\Hhc6PF(</$Di?7!U<6-@#i@4h"%0$RL9H-9 t3KqOC$lhECjtH?#CF.Ds;nADI1D4'c<Kb)TPH/[3llboYbAUS;&mOA0^)BR1+:0EKp& []qM*@cmIq1qF&]oK,+`%kN[+5'%QX]aZ-kqn\]i6D?WP2K^_eI/cj%/pA$OI'7RW;:T.Gle#akm0_);11H/o01^BBKkh3daC]5nc/.S6P0DA6]r13E(41ZKh.cOJ(>h]l*!O-%"kg9[A3pWJT(CXae412[=6,Ahng7YjQ<>VoYsY>;?.56aQBtL,B+c(9:4]43_H(T--b#jp38=3k]5PJZc>mN81oF\,V))#F!FO8pMD:$BI,H2C\n1(U[r.G,2."jbEj4"h*G'5CQg"*o-_,o9Yq1"=MFqm;enNo)2me[s@t.b1,006:h*-7kAL!,dmGB%p3.[dh=meVN/,;r/n^Are4-1`MV4rN$"q,n-M0s[K#J=@/X9JFr0/(gle^TC=,-22CM71id:$F"'M4hWk9mU<\GM13iO&/+F'>'p;UlE'M$X)i2^')8V']\)W8i1h'=]!;D4sMj$7fO0=[r/O;G&@%:E]DJaKDVX0b;LB>1H7\r0+C':R5aq1k_kUe<Sf^G&FYW\ n*O5$F?B^ink#a8/QOhAlkDiQZ<H4#J8!YL-PtV\#\M6im4W'^m`a(4G(Z0`$dYfrTiJ4:a3L0"9mR]<,;rr,PJD=lKb07ZoQ7<@tigP!c2UMGq6.6k"18P"%/c8);Y-)?4n`pXkMiDD.AdCEi](X!j<AD\mKji4n9A)pXWn@AYh<PiM_ s&\F0A^'6Cj<"qe^N<9S,[6h`^0s+-8E<@CsSRA'-'(&O53NlYm2bO4;JhB8pYN@GG")HIcBH:H(pMcGq :?F[04Gkp6$A0AN(!a-1CpnN6U[\[#3%[,FB*e80gs&BX$2pM^C6nk(m/$BQY*OGtU%5(W_A0CAm1 bt&4]UX\t)QHE?0Rr<eHQO;7@o8A57QLJ=5?s+4N@AfN%n:>f.BhFW40Y1^AN!bM][3j6#88q33ddAoQ5NEQ]ZZ<5A=(/cN(5@UZ&7aZos:0 pdrGQKe+o!!c !I8N0Tq7N*p/S;Hpcp6*<9ZEG+V%;SWHk%eQ7hU908p$nboO:5E'(Gn'BG4)&E/6C?OMF?ZW`(lq7QCfPF89#`\SE-q2]N2nstM`&iN_ '`f6Mq6&8p+*TI/I.!kM2c)Ibp+iC6Ll\!iB+2gP/7b)?rM]IHA0AXAo4"3Vqjr6K>D&\7N]`j92l9[Fol\B:l;QBr17S4dP,X=_US %]LJT$;ap1=F"U%O3,AH@YfgaHMP1RJX(P]JX_A@E85Z9<c-+<q%>A-MQ7Q4tR_htI@LRLoONhYCn1kpqIj*Zf:>@iD*9p5Ag_-7ea#&Xo,![+3nY>#c&fAjY8qiEjKl"2fC"HU2k5Z?(VE]lc2o&$N].k9o?*/;TZao'g+`[E/gpCbgp+2[B8nDGdtiqU1t)HBNMn4Q'j;b<4k,.V?XIQbon()B8)jnL$)s.JGUo><)]=+#Ha=+dLlZQ[<$Hg/@PD7fAi).d5*Z_F^jk\K`7&9#>W3V'1lE;N!`N-<0-H+R50#A_GJVdB3>@g^XX`4iI3 KU\6*/:BNo^U-YAlY0L`(BS;EY/rHeA^m[]t7^[dMT!-70VfUgS5`W$mH"OL'h5pO2640 nVA[6'rDE6sDJ5;U?[52?Y03-h$jT#6K23$;7pDLR\8g?SNojB!VLtchs`MR-75n.`SZKf? ?+4lTFJ;jE6*$mG4'$K>BSZf/=5c/IK&&Y`MARfqg/E ?[3n+fd&NKKe-HkFVch+[3ojgg?4H [5<=>]Pl 4?Q9Y\4gsUq.AGsHP3G(#^]6nILm<Ic,Sqp0[latj.Cb1$_<'&M;A33B=!?E GtR8J`:*m5AabW1TAR3tA-,&$UO5*-.H8"\IWSJ3A98-RC:'JBkfU8$Je)M0*Z2(/Egs>;9dR)I\sH2dM3UVKE7l2aTN)7:iKG!$PB>`Er)j7kP:HW[0=Ad@p_(52`>AXOcgkr0aM=UR7!KFs8Q@06JF(.0sSM-*#Q-&+Qp$q=JX3X?O`EC4eAtJ7fP^DFRR>4MT/jnZLqnWafK\VL\!Fcl&j,?;aO@WCJ49e>mJ=]d]hD]qml#mDsM4t'Kj9j@@jWp:kmmo<RdjA67"C2OZXP`<GFLql<Cn].q:kD4qk#@AEhl(%f)5JX.JUo;8ENC9L.C*=k7D&#Xitehq^?AX8#W1V_IkZNllg!C%\4iPh>SU=7Vm"A74oA+SAe^JX,<BmeQ'$+h=c6ao'Y]]T]6CgM3dtR%=)F9Y )&*k#PL;s+'H-FD%-70!r;6g-\g!tCPFK'X\#qB"&:@Ge9((AWB,Z,04$^f4_QWY4Ao7C1F.HAg'Vg. $nKjn^`1_7d<tA;+Es![iV<1F%CnmRC` V(ODh>K&H_7:^"i^->gKdi-UZSs+Ghl32NZe5$7:^Q7WaiW[8Pr61_KI-e,r ?%4n iag8!+,Jt.A<aEV$7Z0]#$?#./o^L?$W\ 9`,EHa*+f"N^:H5)UXIq"Xj't<X6n2b EQ+$+H9bE?[*n*:1dtp<P,!^=Yk$mWnArW-UoC$D9N6eie2lR5cX_rV9%VQR52sc#!:dH<<;nWji^Dj aQ+,k:2_[0#o6KMKL,Sg?0l-4Ps0P,Vh'S=5l2@hRi* E"iSB$U:1>*:COLpr_HK$;_ga[H3E+('^")O6n]N@#:;dl?]09dbH4g^pS60c^9!>RF$PioDhJJb14(oF\AbC&2$JlC(;9g>DniH(`tN'>5aqA#3[mT\9(F&!J5L3?F.RU6M9;'=q eV&>Y1%d]5e9?ZE&7D;>B*-QJSr"O*WF\S=c(qe8#N4FJ!7lCIpn69-<SeqIt(UoN',d0Q:T2o;>3B;W^+6l4&K>;^U-R\@b13VigD%Y.a/c<Nhp8[*1 $JgFIb$*V487n$7/1&/.TKP;Mgh!hW))%k*T$#L-ar2':,!Agb'*#'gQ`_E_,b@Mig8+9?fN)lBNUV=2KRA*4fTdl/A[o=b+0(c$Ck=r>[N?d+4-TRjI,k`m.LfE##>#lt27lgCeL_>(Z\W]$a0Oj-f+t5/rnJc+dj@d4d!H(a3DK9lq7 .mUI$^/HTDL[GncYFbZ& R60(<C7NZV@sA$5>hmHPd5FT5$[BA9A"!n[;#) (n3#5oC#q%f+)65O =tR3\(*dIjm5\)WO)Qn+6,D<iLnD.[VmmcH(KXASP?dr^ToW7;f7^hTO."4]P>9<WU2b.bj$&_K5R)CV"&7ZYTa5% f.^TFUrF]P:@C#fbBbP`1J`2a$Xk(/Aq(/]&C1.3bSV%@JoabA\R_kSQq+hH@MW*l1cPljPQ0Ir3+*ZTXD8eP.--*q@m]q?hh>'P]A9OO-V^f7Sm:__ $=L7SgZ ./&`hE )#T,R$mE"Io"_VLU4`qjO)fQK=2fS,2!MMY?9]=;1Osa^T rQ.OA]NZ/<@MWrQ4)".Z- o1,XjZK\3EB75DCpL^pl8aiUeI9p1EcH16ZQ(^V>NiA</,$R\&J9m 8I'qh4l>OBKadMKOl*#9nhBa`?_:+I]1@ssK`%AH&JhK>(L03mPfr# J534:BkK8 ^QD"=&),c0%-^WY1ZmWg8Fn422;M+I0UZEA<@-U'&A/`2D=Ni88)t\+F+`l569P/Z`7R.k=ei2;CLTo:'jGb;"<m3JcL2@NXo/TELWo4K!)*)8i3rAB4BNkbXSVOA\X"R/o!a-D>SaLdBqBHm=d;O!5Aj MCsU(AKW7US]9e"_9bg,s:??4VZ1-6HirJD"67_)%Fh7MAN\S\BDSbY3rmWT3k39I0329e<2o;0`:W:4RMdp;mN)AC+>@=chL?8+XU6t3`iI<O'jjBo:,RC5pMQOFpY)9c06hS%@<"`N_`>e2hL:Y9)!NU)97V@U(tRck@5i+L,r+iA`9@A=MF%1crm%2(YLX&.ZR6IIFZ$tjZlZm3l&1/[.B6Yl8Ug7V5m$;/ >EB4\>MOL<0%&@d21bOK@_XNFh;H[J^hQN[?9b8(QG7AeG0NmSAE"LC>?P!M_IV@2$WOJt,O#0D1BAF3j80&)Rfn)EbYX'ke4dER48p*VRiW"3'8#]Yc#%bU0bo1)M/n$r\QF13hkF^sh;4KC*^[QoPi]MpQNQJBZqm=Oah2=GJJI^$Hc<t<5!3r1E!-!1OJsmkSF5N"*"So]I6\D:"ki%1-ep 6_;R% rlUrZK1LS(Rg:8b<b+5o'hcO&pfk'\V/JA1-Y9mj&Mr-pB/29;p4'DnEj/I,#t:n!;94qE!2eaa8t`l[-&PdfB?BGSSnti/lgIq#<?KpF,N@gn/pJ0#%(GWoJq-!H#gXRmnU/n`,Rl?'9]m<ac@?VqH:453Hg@8Rr*^':?"<m,_3\D/GbMTa^D6A^r&%7i!4Kj2_m?F'PTSTXBmd'mc,:"GfAph/Oi!D[",k*'?_o)_0nb6MI*;]66oQ?[UDag\01 np6W)-Y/2AVn/=aq@_V@8HVe>K\d%_e7f$6=mP\;_QtEX/_J-+F'^%4Y%:n06T]R]^Ch<t,Ab.::*leb06B=aUaWsfoNO,7fVk/H*=-lta/tQB*VUWl6mcH2k70T9kK$;f.Za<<K`iQ[`ND$'OU5&'Z9mf5DA+5UcC[P\-B!h8:=&4-d'^s3k1#t ^"dfn;p;nbf>sh)Y'i_mBZ^ib6^A%aP\sFa[MNb@GCXC/S]<'jB"jG/)^&@@_ADT^bht;?=t":ZOi9b1lJQ':NR@gU%VA0ROb^[Z5 #Qk5%cldRbrb6$j$C7.r8p<Na0r)^4pWN09k)jZ79g*:W"R[\8PGqd2;e]t5M8=)46^I).[CQtVofl@>?.q"pm=Xc" YLPr[:]nh TK-qka^LA5Q=%ktd?W/cK!old>\C1bUIL3LeNoFO7.j+*Al<LTRbLFoqS`QZp`5N\[r0`f=*k?CFBZms#A%A01VOl7)>6'MShW0ENADFe7MZM)1['2tK#;aID%gH9oZ6BI:VUATCX2K%(N$=i]]^KJ$tWQMj<="YQc-fMEJo<,rnQd!0LO;C<Yn(Zk<^)TTF3-$HaD15>dnqdL1Wc] .n@Ni2psT5BK38n@h'%PW,XRq^gH#A=k7t;4Op\]S,e1+mNgj(:9 IEO0$T&X1G^-CU/RoW_O,F(6rN<6J?SB#GY%;c=B;Glb>mm*&XI@!(]!7>sT7&m_iqo/#QNDkj\p8VTmK@$H;(9CWojQ9@ejK;`nfgOoYbH>E'MQ7MT$;nG7Z'9)^WflKHU@:Y4O;5I\FLUb5t7e:gkN"q(EOdOrehq&r!ROY3j>U;iTK,p1sJ7s1?4jN2-dnArgtpW0D+eC<>efRa_Kh?:aZ8$K1@ABgL_n,kgQ:\n*%tW;#CZ1'c)Bks@W;'5P:hg,iJSFcD$P);k=6mh#A:c/DSOpG9./#iTg57o7rU]Nt,2KN4rW/'!gVA"KgN8U]_irJQUP)7`oU9_NqSfZ2`dhX,ctR6T,gS,S^78>W6hiGW%!rJEdqX)#jsk)6(^M#cAp%@d%o]4dgqLK]5d@jg&pt.dr)`$#$WECm[Pp 4Q #0f]At_hMl('aJCsA2S/M3jiG.a1d@c22R-W<q16KsS@NRK%8A$<b*J4S\Ge$k7S<b`Wqb-lDo;ZURg.?7johY_n`@O.gA.j"D<EDl)KaAe%ce^h%jrPe5=[6sJ5(W,&#A"jr4t,mT]k5fOSl0X/Ts-X&\\_KRGm5]U:HBUX4pm29]b!&Bh*IoWaMcA-q,"Acp:6QQ]B!ntcGY<o]iXK()20/,=>Ib3DX&S^pK*qs-(.TbG^_/E/F'_=p;U\Ji-hkMS0:O4.&i'a+9MObIlfMF?\Qd=#A$pq;N+bh6j>5;Qh>$5 N!dT&XSAbADW4T)`/;j,t%IK=GA\SP??R/f9!'E%$7mK\tcioalVe2g_FeSCE)qLAstRl;mOLhksfHc>@d&\h&FsjdS/n\d@aDA_PdU-_%fV>3++RG=qc>T:(0&_G+9U;MXYUK\AO?H+s3D!R$OV]mYT#dE#g_RWkM"q(I\AB81n7S%M!VB,O\6)l9[Cl$ F["h6ARRBHh/At4ah]s<"b?4;fL[9GKmc75:A2r\0'CSjY\ ?f@o]pWN)Lo::Y,-#+jtJ`NA7`[8Mkt5T5hqeAf:tkTP[K_,GE%5A'jM>h3J@h%WG5oVsbDHOr5V9V+Kq?iY7-:EQ)8fAS<\s3WlBPJO7O]$o@#L@.bC&hDoW<#!.8j.<deSSBIlfMlFMSV$)=XP]6_r([V2O\ddm C27IL+'0ifqoH"?/,Ji$R`$!_tN4=Z\^BU&!(PKnsrC8W$*hPSh!JZ?:j5e%A<c"[4f=Nao3gOD:VjotqmB%&gJS,+#-\^8Tp!CWGBdAAD2!,%:H=@[`S@R*WNnRU?T:Oh"Z%) frXRaX=1(2!"r$/b8E!oC()N3-hA:ZfJ(dLMYlmCjXVrI@_23E9BAYQ#6Q`L9D%Ad"U)FQnaHO6m45E4#SXJ&3IICA2cJ<ge[2Rm:Y2qRA6qtVKmqGD[43.!'!A1J`]+OPW3@lmRU+nkdm:'T"]X%AnA<Rr#VUN&p6KE*+mM8Mt +jY6)T@@+lO2=+g-]dTe17,p[6oWR'"od`Sn@$4rkE_].h2mZOqp@rQ*V>/YVOL?[po`CD(-at 4c#FcK-NZ'E.V7+pq,(3OrT$8%E>e37o57[BeTJDYASSD!^;%ob5K)46%67J"l.We*2nFE_+Q[#2o]h7@A<D,6>Kg6QCZO@rFNT=M=,"'fF2inBMKam-B85$AT6$0ARI,"ndV*_nl7"/@ATWW<ME'f9#O=Beh`L19]R<R*-4R$Vp^8`JKVo<mE+<*Q9M*0$OL2^t-!lnW]fOoSca(L/ENf]M_6_<.\3/"Fldg'WiL:?*re8S-Af"tl@:Fr[8DnZ-/U2!1LUB77,j2?9\K!HN7GAGk9C#At_7\mIHZN`enlks.BT]m3?[SQKS_dd53bMc`7f/Y@Jgt43P"PltP7MOD_+h /:ibi:^[i,NV0A@6UI&?iC@hU0iOM8OG(PaF)]Qbm,l@82)4hd2;nqsj@&6sdP]K8_dH?MCL@kP XP_AA37%*a?U9sh*Q7JCo;fi!OW"Z>Gg:k39m(>t.AWg&?f"3>/Rp/ahL3dtB `2/$5?1bYrhmJLfcMKte`@/n ;s\PnT/el`laD&EK"5+(3,l*jjPWJe(E7Ikt9cJ0%Fc@mm4c3s^AaaV6B,<-O/m`>G+(.&:#aZ#9-4LM," NefR'XeH@nc1AJ?![jD]Ct+iFl[%%TUY_'I:%<*,/&hC@cWUg-2(9>91LXW^WRb6Z1Mpp$-:l[ DQi0AoqIoO`]b[G"Vn:+jA;%kO0-<5Bag=g_$P\tZ\Ufl!4Cii ;QkA\1%*dY(s(sSHDMq=oX*gK?G>A!kST(H.)`!NNb&A>'kY/-)&n'UKd',g+4$qNIQOCHPYBJ7!80Lrt;"M=>5X5G$;DHMNYQrdj!jJjQt1Y!DI?Bq)ZRZH>nCk\c44PAC4^5PLIc\g.285(6$?(c/!0j8:NCC0RiF*k?AT^qQatHh0"d(C1H4W8P>>B:\"^Ui?A\d(YB mOnh*JlA 'VqmWe\0q4-=QqaMbKSI45>A,Z>_#qfRJ#[:c^r\S2+6le^O/TCPFI>HZ8=/G-548sSdom(J?C3[$25 @:Oh<;JJA6)#$H'B+`06\Pr)o%;\`#+FA@:D7CMl8."5'AU5Y0UCNL](BA2b`2 $pHjf\&jS4<0!`nLbYrA eMZnU`,o#Q.[: )3-IZ>^(MUp29?DC.a!)r7#h^d,;D1-coAB:U;=))#Ng!GP/>"]q>9M(1`FW0a#Wr$7"cB$>#E  'eDCTt]3.FS0roi2q]J'B(JtbZp-es2]((SleEpVd4,B@X`=n,LT_b+/I;b?K )<6CS7;lA/*qA"_;J:1O=mrAgeP&JekLD(Z$ffEi5O(E79KWOfd]SG@7@\\NM$^nV_B/US&U7s"kM%G'"K!&?gb:%Kb82?&'"*Dt^bXt>k9E'h,Bl94+.Ns=el@F/FC\1-sA37Aa&<4p,BO5>LLD/c2N@01M\pDte )*nCBEAN]bo):3V r8BdgCl Jq6TUiF[>CJND$=UnJftI5^ApC))lfM#&RX*lFnJ'h5c@/WQ14=GCl'6o=;No2"C"JI/TgW7SViQ/(cjX>M[@.K8?RN([-2HrgS4B.@A^?AP2??N`")AN+U<@;BRAOX5=9<)\F/B!sid \]R4qV(INR$/o\<Pk&-gc?iO,5B7njk_6]3dW?1XXpe#RANAh@2KF'\:N*P\b@?SjE.R@::J-L:8[V`gH?3Wmsjm!_Z'K.H:mpQQ?UNbDjf6*$;S#6+C2eItQ.:Iqr2% CQ`VJ7t(&Z'[ZWcEZ9YB[HeD=tFDYl^a2+=Sh!47W5YsN\Y:cXME$Mq_4SE:Yj3_ T*'/>*\m<g[me*gbD VfKt)=NW;/-_4*S*J;Q_(j5]i$Z">(_8eC3ki.QkkFlPkVSK2?HWAXqMY5*L<Q+V:HU=/[P#l*TEt!fUf5..0q/;ANor()L]\1ZR9YZ!^qaJt4dWt$AoGk?B/@jn?;1LDiLXq:qX8Ip`ciQ>87TOE`ko<3Dr-QBPV >cE<1T([B4^_CgZ,4LZf!bt)t9iVR(1kWXpj3-rrq(aG_SZM&O=-2QU37V@gQn@Sn,/!HqiO-gccspXsa1$%e, ?Vf'5=@/e_,It<FTB-]AtMt$Xq0jHV.>O*U2`3mYcqB^eZ+#Adk'>A;.&2osb[=ZEO@^U#:ifJ<;GgZB^o!>D5Gc^/Hq9XH$KVb=A?c%<Oj4ai"%dcm*%<RRQKfJdi#<hb!TsQ$9`kBADMEk^oYa;l5&4cFA<%+]A%<Ih>DI294lh+]p[^cDj?&J/CH>p>,l/_1E#i?-YZ-)._(QrZnSc5?KekMbBPs;]SmRbJ=(P-?I!AedL*C@,$dqDm%P&*/*( g*qmb%q!nn8.hs\;nt!UUlXRVsAQAE*#qaO#Y%E)r"LKQNJ@dW"EfX)+\Xf=5.TH3/>dJ?9W tU9s#&CHsFT =c`3DHLNJLkA1cJ"D>aQJh%<X8.h"X.`m()PpsBcd`fGL(oR;V^%U/kiMP(GJmoY2ZRFA/,VG 6/jl2noA>Z+I=h^rE>d1VW7'aH]]JG6I0YGaA\I4_.$q\b$R:pKB;n)m>%K/0l9LG^(bW1$qiQ\NbYONAA%c. ;:PFQ++0-E5P^s=7^MP8$)rr47`":&$='>ihiFb/>A^7^3UO39<>#]l6N[%B8M$t2jP@%RBeVOYO0l]pOnrFAN&oO:7o Ts,gtoYh7:\1!Bh9)!XOeCHYE%9C8pB10HZh'L-a0$c3AS=r^a67gCNkVht<`c_]f>R4ZAitLW!L;og%CIJ*^T9RsA,q1:c#X`UI`K>kJdN]*A"qD#1.Ua/!FE7e?JEj EGALbU2cdRpPf&=$do/?2),R]p 2D(HtnNsNp-J+k0V;gb6l<gfhoN:'4`=_XeXR ET>2;k$e5o:JBCXFf.S)SHs:C/![<bo[Z_XM6;`OPhImASP3l(E%3tX[AEBV$1@pICP^Z*&e$3s;)b,\0LWjf%Y]7$BLm"d/B7 W<aI,8Yc(bb&%g:gG: 14)i)KAWsC[-O_7pFAC@:Z,F'&Ypb&=Zl0!Q!JOG&_S#&[@+1a@!<\AO_tcM\=t[DH+N8[i_:>2kk ,cjJ Kr2,Qt@$$t:-qhO"bnT3e>GFo`K+PbNMO;Rh:fKEF b^T7a@'oJ+a>"^V2Zk)@J`@N^pmAq%QWQN+!+M+bt90mtZE0 `g%qYf,qqqpKg+tr6`aA;Of*\RbV#Frr=&+-pqWsEFAZ/&ToT/sW&kO_7Lt4FL-UA:phLq#DbcirKJ;:J!iUhKdJk`Iq?!8S=dGd(kA8d;klrp4J+:88cXMP*\1)m=,E9k=hd6*I*90X90`?JA1dXAYfX!D16fdaBiI2gA'(;n"cBp4P\XCih-r#GAN3R<%V0<q2I2WtQn8%:*V2D!F@KPQf[A1`^V*qr7U(D%1C0t hd!_.2J4'jr-]MrGV+bo'"EoM:^a3rR^#fm*eQ'T$gA/d'Jp>5c)Ad)p-E(Kqk78CE#O'\:KZ.$GT^d*>)K3MQq&G=R]"2OGEqP%;BH#9<f.r!D^/1tj[ik8tIpRlXq@#7H8R3rJB;AKNR;68#k&"1O)^$.PB0(p]pN$R2i1>-%+i4*lhab2R3M5=b(`WeqJPG@;KkT,dQe)M*WF>&D_N*ib@0E#,[WS(Ne3YPtT -;'m-BQ,jbp'eo[pBjAF>f#h2b+qRd>%^++bN`P]?CNq2Ks$^/XnGO3@G&rEp\_&AX7XH,7!gr@**7'BiS)pERcqFmntb5'[=Z"c/#p:(E@_eZC:p?kPH=o:1p@3<DV&e"32@[_UeiHmJ0!:O(&qs IY$4-QQAOdd3E[`ZYmEClsS?`EMMri+/A5,= $A=tYa#SY,_5l?`F#.9"m0:5^:WAV q_6PX`d8'eSS >)J$\A]q'*C]G*9fa`jeSZgj2laCfVS/+Rgf9=%S_KB[8,l[@`lR"B[o4mBA-dY!UM%Q2c=13AZZ[6fc1["[9g\"=Uq5Dl@d4n^K:'982?V909L0= Y\5AlX1V6$1m'%]"ERYJPnT)Gl#/Fc<]k`/U.[4;cR[b)j#q4q0Qpc=c$eAr-5V+n8(\DNtiJhPis3:@<.F:[`KrKL8W\i,[1].b((pCjbj%LDh0?H$2Z*)J+*Lc`jQZI`Na.k>`PhQHNn2A=OJ@cppcMK00LPg"L@-WWZ5K<BSbLspU\@C<WdG(L.0srsX8XdM['n=_"PZ^3;e\qYL6fAC&_ nB8q!!BC8%OOH<AI)LmB*?$M%l),>E#s_ldV&Mtf)3DBA%!#?1I@"`-^E^=!X]4AVDEQT#%;70kd_4V"dKX!j^/UfH'O@[*IHC(b]AZ$ZhLM/X!0/Q]Hj*V%k0mI(Y8$XOn\.qIn5/e)B"I]#/Da6V\'O]QkN_G)[I=8'Y(Z_.RqXB/)[MIAq#n& +nm qtG6g<`OU\iKY/dQE6D5kNJV[rJ=8[(S8T$Ig4eIP_Ff),<Y-Lg6  ?7kM]6f@qqRBc#'l&c5+(&:EVl3b&X@.cN75BSO1$;i\+E\*3"9S2"%6p3Nm2h_RA:cej+ESdU8)";5DlLlMcKOnT3s,\-,WoA:6P;"k%&Yq:ENNZUHH@`?1JHR(2d `$:U,WQK.$OS'KQn*;:-2Z^,=[ml^t8N=%6R]Meg+b'GoQ5DWU<q#g([:WBVRD<Sa#N$;T+)bC+gm]pm7]na0UeM'Xg!KICC>`&Lp!cC phI)oG57]I6<N\U0>PZ7ciGAcfh87BP]!`AMF;<5TcIYXOemL8En[ag"!hb]T(1\M&7[4C]n<>X,.(bE"Z=([5+>& rentPm#3'4/>U[ mc^#Z6rV*\t$LgGp3$:*IG-1.25FGebgA4U&coE".Ab+j-&ZR+E*e!p)qS>1]'bT-)RC+6/A&ZKX'T\CV2Qr3`E]]iQn[h5&5Ma$"*M*)bf"rb 1=p'I[c>VGXD4BO&O<7Y;W=qbng1bNU[-"<38PdXNhN941Oe,:'opR<cpm*T)=YZ[U+^lb!4+T:-_3)P(\78hlkojE!!m%qq5ZX'GMA.Aa_GfLITm/*r&Un0b88@Ko[;dY+]\Kd9AsWk'(]r]8A]Gb&^:W;Sj)!a#<UFgJjdBtmChsl&Z.llni*'T-"_Mf#%g_Al8;b5j'rj@S=.mIZ7ojf75;'3D/$*P>3b^,0YF\\+f07p3"0lXp,tKtrIL.0e^*.pf'00aE$R#8W]O?4=0QB3LUr?mkX7B(m;)co6E'"<1lQtfQ@5mR0YR*`FFYID+'S0K,Z(nal4ssG[7IS%s^48pi2B,8 (A)KiNFLc6m=&O)5j2 ld*[8=I!/f h4\G#i>h?@8P#VEE76!^E)V!l$DeRMMriK1&8NgVG;f,X^bfZ8;N4$nqP]C^A\%?AmO '$aWQLR^Va,+Zq/p@aiWi?>N[Z"2S+^e]cMRH;7DWNFR1OOaj4sQ^l*]XC`tZV8T>FWeS8N`'`ZmSGbb2eSFN!\>bDh=Mg:S!ks4EOLh&T0[*TN_`kpiT1=?:k_k;Q0I]3Nl])gbh8Q<Mb\fM!,kf^g0SiACn3fet?)1G!0*8a%iPBKq\[R,k:#2^C8>e[+!k4U1g]>XHKo9tgI1bb V:/`F<Ta-5AmhPmDG^RO5!Qa),VN(QQ&B:l!J%5t/$goAC]T P24"<X7?dlf,@T34ZV IWKU8&4 nOeO:@3TsdT&QDt)-fAeoar"O"t$9i:jHkR.]l1b!B?<60LU1qa*G4(#EbT&g,JK;Mt&l6SE'<*BTRst8=MXMik.YP=&VA jG'?3pGS1JD'm4XXUPXg@KJiN.5r&9_0H,4ed\JW5RIJ^#gOR2_Gf4J!W6C7MX`cOt8)V"8]?a*8#baQ9^,tDU#(%QLq,OPQ(kPA]^`sa3$@NW@5@2C!,V">Vt5e&D/pg:(d.@+Ti`LPWE+W&/"YVOO`C4kk nOkoUl jY0"< %J9d,%lsY,a]+`A!Qd$WR\n:0DE(<M`Fegm=apA<i(A<\scW*^:1j@dAQ-5g$ommh:m*M0tE97_NDO!*HDCN!c"8ZC?_0QdHdR0hP_s\0RX7,JjM+k\>XF nG9G?GMXFO9&eBQcA$Ma3]LQ5RBX""7_De@DAoZQNAZJegBWjA36hDcEt.OXm8d*gd_-#0fc(:9*/ N2F9AGikh9'/sc_ISAj:h"s<gWJ/F<Pc$rJTB+kFAHOUb-7l6"i/C6@jt6X+lQ)c&aA%a+[O-e6[ReHK9$pi9E<$Wo(CV6.*7M7,m8[^7p5A#AIIcVqGHt AJ!PFdJc!#ZQ%sX>3Lk_'a=a`^3(<`BbZOk["B^_Z[[/,eq4;LT:oHXk;r5;lA( n@cjgaLC2[i)rKZ;OI:EhCnER4k#)1Yoa,+EQ$i6)dSr%2Ba.i3: Z6SA($a!gl$/nC6>X0EE_a72CE`nHL"`ZGU_5SWAA?W! (WXtM9Wj$I8P'8dij.S0aU*$(MBK HLH6'U[tq#JP7->J=na1WgXIWFkjdW;1Y/sUn#bTMqen^`7bA>(^c[!Kn[f7p8AYb(N2%5\FG-L0^5"qMVFfaV;sBVm9oiEHgj8H#OYoUjZMNTL]MqdZ!s]cpa;;lN)0USZ0k+_G!MnioBE=e0hs3r-CTIilr>3q]9?JfI)sNDPA#dp;\3rFdLnA@Vlgp74%r7>Cgf\N4eLYHU?3*\67rK]pP cW23D84fAQO=2,.p#g4RL\<&QdV ^;qPsYans`GF=XZhl-GE%EW5^<fLR8Mc7rU-$*iEL2T/ZkjAp&o.scbL;@g\c2`Ut7*/r:\Keo]K_bGOH2)[EF])dnR&TAp^JaLIgA!E^q\*L0aAH;o!`+A6'OE63l^,%c`P_X3/0 -1b3X516_L/Dmt`5 B\A;NM$kJI3g-**5J69q4m:,4kr]0<L1`rC%bH@DlS,]m4^6XAY,A>K=(+(V=OtTqc&:bh48P[RUX/.YKGC]^DA<><6b=Gh2Dq04>^*V370c+O5F&r,CEhV5fK)nMfG)Sr8`i/9K-7fO=b@T+\J+7EJ@6klM`Q4^Yf+e^kXIrNXAGn;/:SJYhcqAr=0shWAs',%1sM.3OZQcJeJI`fO4RV]9g$#h">h=C.AR^)4e&Q&K5,iZ-B(t$:NFV#FF8tY^GHO5n1q#PIMZ_0JrgF[%\I7R\CK5A:-rc-P6fFm:TGqbU_rjs$q+O(I4So>0[ApW!qQ5IQnZ5GHgr=EL-H20@6Bk(AV$0UUF_#f9(6#g":j!<iI!+3'S0AK@d#1A,FO! ;MDIY!d=Xf#.(EVm;^>Vsn&pX)b477Sif2mg^V1$*D#_.DY@_CmmU-8`$i1,h6^8U.(EtH9<m]5og)eJ!bbP[b!QGEpJkP@:bmPkCONM-(-`U]cXU]gC"%Mj,@f%/]*q*9;UYd9!)=Ne'4Z7rtB]b9pj"dpVkMk<Ai)F'=H Bh]=D#&BS9_cTZ]-B`b`F&?;N6baVT8Fr"t/gerd??\<J6Q1bLprbQH\C?&cHaVI*<5>A4d>@k<(tQjjl"\gQa7PArYdrTe6r=Fe=T9cYL&@LU6=r5r]hD:o42!1ARde,?dMrkU;`BbNYcA"=KM)hRQ`r\hoQOAA37TNtXr^(6q9@=N9)j6I!8CJJl!pg-_M;tMdSa2sD)B&*c8t/dY0;+=;j)*-03I1n 2I7F1jpOc(ocb%%L/XUj\s$EE2<aC!=>[!<;]8k#])^N+AlXfNZ6/jO^Z2^!R,"s'd:k<[[^ig6Z6W<#(\l5m0+^GHLN:tD`4,k,D:V*HTp8)O_K7DO[>f!AM&]rN'< MOn)D"o@mK?jmgi%FltcD*0.@,-H(e6!!F<5Oa!Q)A4OHKi=2=NDBR6@jDrV&Wj.p`!VSUb0Gh8*Zjh-X[3(Gg3Nl0:'`YMLhApqnB0#aJC$$_67?8k]:lA:+pqsqs/Mm4jBpTGGsKA8RH@k$)kJI<+c^HbkSX0%Q6i%m;?7J(<X\V\G.lX)qP]=#7?7HPMQA>D&q+P0N@9)JKEX!8dCA0b"8TbCZ-4C%L?#,4$UAo`9IPt"K`Sf`b$7?,ne4fS';ok_3l4HIS+7H,JV(5[NqX4TO0KdO_&'"*ZKDtK30&f;<?lD/2D8O[cWP;=*.I.YV<lKc;^rDL)J(OgJN/e4Llt[QV;l=qRjX.7=!,$.X15V:7[?[j/:bf,_PN?[&7K9+`.ih)Ce^:oh[ArJl(9\+)pUl>;*"3p#]t1@ZYl82b^sjLL,;P)$tJC='b,pm1Cm1CoL1(]URj,HA?_J9;VST47LXYmIq.O^,!54Q4RIsp6QWdbW9CZ0g-5J;Z1i^4bRIk96r.nI.jUBUtc^I![At*:&UE(KjS(/ Jd]<V?>I,aAkEn]?QaL!&MV:b0tVF\$_(<SjK60T/r[q;Pt41mA5qRC]BRQ@pX14>fq__Uo3W'>*p+6%E,[*>T5hJR^FkJ*$#43+VhrK&&p"?K%S'r";pKQ_1qb8JL_:#Np5>I_Oh%>m3;' $k<As\P,Vt*bEObBn,kh fBU+nb_"'I0DD(6l<oTJgP'T4c*.+fp4JsAP^/!;;8Xod!mJ@s<1Mt= +pNUJJb@%VoPc.R/,MS'l?/8OG/H$1,l09FJ('-2]H,!*2d2>A]i&P3A)7WUXm*#ZnF7kU 1WcU4+/c,^ -0gAri,BK K=cYV*G9sXa#/#<iK-Y]`m` <?SYcX!]$%0N^6-<p.&AGO.s99D)Qi*aPR^QNn;XEs[#4RPj`<*i$/LAdh>^jW GtqIn+LA4/bkSW.9MZ)ZRbNBKV_LN\>$DohPie]e3?rjWX GP.8#A2O5-\7"C,KPlP5Y&U2[KlMQo25q.3EZ/#]X2UYU:gAI"E4Yd2`IY%O<$ptj+Y5]LR'G?P^<NsgI_ReKZpmA;8UocDq?Q[_Z2l6O&k3#f"AGEA(!3ZZ?-MWZ?HFP%E@kcCBcY-\T%5'#r>mRdRd'qh/>A?D<V1=tZ)4NI)B*EWZo&jmiXAmqmZpcdMPN0mA7MEEacOQF;k,<!a]92?7Q#=KY;>ch4Ys!%UG'FYh>6K5g'Wo]c.oGTbGS-?^eAW\3VOP=+T)_WecM?5/9/6e//Jf,$7((V@0/%O_k?8A&H!C(gZA$\lIS=bt.=ZY@%!*`3#1(<:>NNP_$?-H;O/FPOsqr#q?B!C3%4*:JXFlF#cLCIjr`AG:B!d'B:ai=HEr&4cICiI=dGf.F'X;M6n5/S8'LkO6,6SRf"?UQJ 8,8[=tiC(UO]J/AYl0_?+#]rgkV$$.dI 7HGbO;WJ8I^^/ZW:jj+m+ZRir%>jmWXkmbC"Z$[TT\)Y[%)L_O+>NLsS-^\Kr>eStgZ#G A:R:mQ9l024<FA'(Cl,B&kVWh\=L2ERI8@k($PEKC9gDV4&.Z#nAD@KmPcgt1Jr[\\6(orWJcH[!Z2B<ikM-PQH<$pmTY\`'3d.AT;,tq<cesEdq78?HYm6@#LLa ]FnE%MAW6'Dp`,]efmi[_-D=;-rB8'DIN4<PEcrM>Xb[V]M'lGW-%sjY%:s+b?o?Oqid<XES%Fp1)RnCg@Ab6dfeJ=tRP()n5i@VE;W;jJQaJi_rNk5gB"LVAoe%SAp1?F'I,$!Zg.TO8r&\c4Tj?V(B[N!&[p`Qe0;b;S$;]A^mMlFXhq^Ye2LOI%`SYMBdf>&TFsJ@HLOL+=1SP31P hSX@eR@61(H7f\W"`mdPf:JlLE\%sVboqP4m\Nq-1j^;jA3521f9X,Aj8 h61c=0G480E30bdNHdj&m!Dp.4OQXj#aaF!H!=VO5-2R)NsdM]o;)bs d/2NC8_'%hG"68'4CP22i5 ID*8>Kok0XF^'mPq6em/"*-0SQU`KfTbIF."oVADl9.i?JbIjp!>4;qd>\/mJ%tM9S^(IBK8CF!'a:/*2^=R&TVHG1AoIgh$;4MMC.sTZ18b@_Zo#F^a'lH%VkRFeh2WYgs>2'$]7o 4)V)"jRBN-OqbfGi5`bUbEG^cc4TB*.I,M<9sX"\hpBYZHZU&@Mp`(t:oi*W:4eUk:j=1q ,E77#5=+>#V]iiI`,A,]$+;aTN]qO^elX5gd1_cZJ&FRjfe50o5YP2'/3.:tN)GPGsWD^3FHn<Po<9t.kFBFP/9mJBM`>qf7Y)jBEs,'lX0J\@FpCNkj$?;b53k3K,1&Op =ktW98o6go'DlS/q$]6qIlD'XPAPmF+52*KkbNsoh;Et'l?WA^MS,cWZp(t5!bSfAhfY-_Q]XtfE,'-9JKs'SPbdC1h*.2MmDb#CcO5ZK4qR hc$;0*<<]G<3F)bo 'As'2@+[.Oi&<\UAp2/fMeA.>A6/$Z"R/ENAd47X+n*=b4Q+FRK00@a(!! leYn1B)b%]n7>`@,nF9q4>7"BE9fLGLt1!X3%,!\R5KBn;AUtn2@2m,"#sBAj`+n(HN2KR7c2Q/&9'N ^XS:_/A'igE2Aj<AhAZ6$Fft3'q+OB(1$aU=,m9X;.e Y'7'NM[0iCbgc&3f-IbkVUtpXrl/j3Fo)ola>G,k@@A^R,I/t:L?DO'U2Prl1NJqr_k&<lnWkGs8!hHDhcll%pi2n[h<GItgs0%5\ZL<AZVMAaF6fC'g7!rRX--,`]K^0V3-AYVLh&(K`i^C</qj6C(geKYFA@/n_<LFFh?pfPeP;eVO$,(]]K?i7Zkk]`%fF[%c7i\RUKTnKcM7]NAd^e3=bpDXtLGb`6OAQ&[<Z5HJ9F^>80fZcK>Og<s-&1HYFbg8i:+=@8TC6GL^"HdhZa@D$#-BtK;.,Vo(!keiM:(oDc,3m`!eK8`/jha2Z&Ch5ohpX1bFM8KJ(4*T_*g;DQ#N/SH*GBlsjtIsQ(*>'6c3$J];t3h6CH,g2P/MT7r?t,TKRN9\;OM3RbVC0bhSX_6F5R-M# Tg!EoD%SYW*1Qb)JLI/!MfTZ5""s:8<fd)7^`*M.ZA!F>Fmr0*Tp7P$FXqJ#%`#=_H<?MT[%;fhQrT,R.=80>i91XEeFU(m9+m2hA%ZW4E[?l`=:QW"mdF>Ps03m<9`7jB""<4<6$-`bCsKjMAMPCG2W BC?^;O17GSDg1l'"Pmojqq0\C^,I_\).2+#%I?.kI##'n*@PSh /o:lPp2Z4b7o0EQ'c7%>Xme8V0/+A[A-_n\L\l)=Lt!%c70O[C(7qZ&Xk_@jh'DphP</EV`'W[cV4KO_1+b_/GBE0&O$\aKSBddD2ne#fjf],/]]cZD!3)XUJj3g7mPPs:L#THo<Z&n4>/i7p^g2br/7boPXRH[Eo?l];bY6T&LrD@<b1'?tp2Efn$Ai>4Zb mjUf9>\b\PdtDQ :AG\H91r>R(6g6qAb$<S#hlo JI:@*8EHoEei9ARh9iB(=.NH&4D5cDr#k5jWaF>7DXRdjt&#mdFFjNoXE&]0FU;,LKf.2lK`7In."M0#RCDI4:C;p):5PNIKrL3?oqj=BUQ3;4 AVCAC&1nibS^kES7a0kLA50\3((0f?85.QdN-/k:in<)tFMAkQnN#Aid/G'-+((:Pf*)lh20R&gpeI7U\Yl2k#r3OD%VKs\#i>oggj6J8"N-QlI4:t=+raJWD%Fj [k"AM^O5frFf[K$SI?eH2b,*H<YJZnt5(@Ir6VDUKnPh:9lsHAn C4]AD&Q`"lqil1BAIW+FfiQ[K]K="X'dM&Nb)L*R!A?Yq1C'gS(Y0#U'52,4&f5$">_FN4iT_2W5`Dk;&ib\_qM+VUPX*#<Ftd(f`XXa]BO';.a61BGK(DaU7XWs^d* f)=8R\0C01IdA(>_o:LX2<lI18nD[aGi/.oBOg(s",&Y]/[.0Cm4!IPP7AN-tDC@o;5--DgBk\kF'WV,>c1!mBV<XThWa\g$m]O!+H,\9eSo%+^'A:iV+#"3f]=7d/^gA?GE6%HH@9rXC+ObJApe><4l/QA=!gg5c!dX"1f/cJ1P((2,_LkH?hi77HZ0I=A:fO?4 ;$FnW3F6sg?Oof1g'GCA$&]Y)..5U76;%d!Qn+-kp0BTl'km"!0[bL%2]?d_Br;oa(Z>qta.#5A& 7P;BhDR&rW^c(N?H$ZG&e<h g$)pfAlGAf;B)gFteIi2E:N9jGntD&QPH*InJkOY,UN?L\/>E-b0]m"^:$D&m5aAeh=a_.]970#lT,`a5A]BVThe@Uk)_8 ZpR+H-.YTY3;1>![%_HdMoDPG"s;(hh?NRqHZt"eroGFR9`2OY#VA1#2g>Fn`]<sQ]!,Mh1Z'3Gofp(K(sF(?BUJCHa)%'=L?7gb07T-&X:'n"3`8jh8kaK,]9IG6\/<Y7Q7q;RkiKU%r-d\^d"Q'6c?8;oca32VQE^gU]<0tsUS7LHp?1kSD:$*-:H?mB[-IjN/a>(`5fS$U%Y(qmE"h Vi40&3B5$.\'V/S^Mh$\P#,Z%43m%R()7^iP$oVJV[p@6-t)n&\87=]I^1L\7Xm$T9cp,j7KZNa<98DU:iHc [F!naeI4_E3A15X=K/?&%%JQWN=Hd/_DN];2 a2d0B4+h6($ 2kUAp^im/nP ZYNj/+7+E>\t@9r<sP'k&JX9 h2^2QD0/;go?MKAsS(<&3AQ7?MN=Y(hX9#b<D[$?'MdqLikpX1?<#JAeA,Al)fG.!]CD-s_Ua,+/LCJ+o:SM*^93D*.CY0A^#B<a&mO[2Mq8esn=W,eEtLci30-FK[YQtMWT54=])XZ;HUZHN[`P59LeeKg4<k)2T&qCEXj)?_&HTFo@r`sBp6[,T3LNn:2/3&kE;=g:.(UH3`[QLes6A!@LRj8:]U,h)=/_'_!j`(\ H!Y:h=UA.sclXI?ASLiA2hZ<]`!HI4AtQq4GPikAtU7!b*@aDO, 4?s$+&T9-69GP9Y^U%#@k`7.hBR5Q:s7:n8AetPr3XLSCs)f:K-a9lQ"Z`fqsi0$R,4t^AGMR4`B5smUM"H'B!#]&R-[8de^6X*:Vt]6ZU5(6:*$TNY_9nBPd^4GTS&ejf5Qdgl!:r3+P.`Vf$g#qhm7W:A("#<bVHoA5l^LAN @=:)PE#&1b;LF[G4ER<dT aaN_pEWe=<WidNIg_Cm*I&3m*%k<?.U8^XLB4il7 33F9)/hf*'VOfP>LReJ6M*/8L>="H34g#/NK>Ad1 \CmZ'F^F6E`PKDjC<g,dB]Rn%Nq@&CU_r_"+5=832 /C`(564:VIUVLcC@;G`2qc>)efPUQ&-XD]o?Eo%(9,N3NA#Z[P\rhcrL<84n RsP^.b+KZHk#;\'XYg'knHL3 gJ#doTCiI<lA(Zt`]X[S_4!d=JjP$*n6NPl_<h`MeAmQQQJ-.p6;-8sU]aAG#gl*/V>%XZ@alWl]r/9b_7@0q/TIMA%=L2AbG,3a)lo?H(]!$t&k?)a?b;gpK@tF:H)I5+29Z@Fa8^58D%0DO%(5564 (&RH(!OdYt9-C=.ZJMsfhMR%ZFUc(Y\\5P!gcVp^<TG =d k!i*9tW,f9'PY ,N@rR*Mt/]GBr*sno2/TmHG];M!7a#UT)53mfKL0Wm=+QW=:$n*8;Sc]PEf@b!.7XL0bg,],2MN+AZ_UUA5HD^:%=e,_A3Ep[p/B`j,lde1I74sV2@(L\_L/U$g)&4TH'`tSC2hS;F=I)=i&m4G1eA-$a8dDf?66rdS`Prp!B;)SlXA[N=Lm`o.4TtiFjSS):ep\pm)2,T`GYKK8P-6Bs7AXgQdpEs%3"lCBDJcEWZiBLm)*#P8'!L3M?,[D6AtH(#Gr`5Uc&=XLr(p:$97R'qr 6pH,a+G_VKBekG96_MG(`ps(p$6`)b#Kn*8Rj0Q@<d/A#SmpWSX-;Y+*p<>+5)\]*)N .1<"i-71jr$AY7p7"9T),c)=`S)N*B6:L0U*aW-HDXfsXVf&a<(l/tsMn`;`[l=;f&rbgcDP19ZEZA`M6]Dis-MCIcAO6c+p_Cjkirb!a@hLMC@MqCs2O`]B#rob8S>_U5OXA3pr&39^o:+e9h<W,t')V:Kr#7),^&"=l-iNfP?7jcT;/ZiA"'`s>i 'I3"4N@<qLlApX^qJt`Vt\.\=/QA^Id:T_<*ecck=d0&h/J\hBn6E`[D3[KW!mkdGI<[=!(1r!`NXLXQN l*>\J7Xa=lJE3f( #c!T]m0R<c$:P,Xh0(nCGc2Pk5LWZ/J2$2,aFQ8'$44__AEApbd)#=;YFi4t$aDo=m-VO\_C,=/'.!,TsXFDNePWVRJ`3;#D%`P7taS3N`rVBA2d?=`[b3(.@KRA82@U_TF^+A#KFeH/#2qiXKa` AB/[c?XX::Q4qemr`1IjR]5X`?\]o-( F]Ud8/Zd<1/AeMX7'MXALA.[EWo"A%')ZLIJgcS[>%].V"YU.*=4nA:rY`)W`4sGkr.ZjqmcYC0gq\QpDs<Jq5=BFg$j"4bQ#0b@%nsDE5Gdd6MQ4hbZ,4*F9HTgOPS[=['&;b<tm$,OahH?!AiR6;.8fL<+m%@H9k&=hLI=Y9V!2(p@>/%Qp5h1>ZaEk$iG4ddArO`raj:VV 0a9Co?8!$SI/:Y'1@hY75]?Ff'^? QFb4lTA.f$Yl90*85i)JDM)1n "UeV\ZcL6WMYrcW7"8A=OK YqMAG+\;q"$Q$C'>(S56?>3A2UgAC#$.EH]?mL2VM;j1kO[A__NaH)etB4AY.nDt0PlpQqVNA`@O>JJG]5joI]sKc[gAJ3GibCf`aceB6$AQO@=hcmn[:%9WVS$?\24 o>I^]qF01Sc18 KGW9[F]`I"A$rA]$6Q?OnpSHiaO5_q'XZfnP:UNHje<=W9eXhr+2qdXobd8)-FRk2OK?\GH<Z?V+jY'U!IC6$5"WL;REHI2kE@>PXt\?Wk`3n?d%5iZZ.fCG#MDi_2N&OObPNm(' SW:B8jX`%fFdY+_'f#)B?:*J8sbf$D8f.?<&Hh-37eQOA$E [(Z6"/H`*"%I??Gn<X&q5,@D!$gSMs/ :*&%b7,-&<;A"Bs3CMP]<&$r=Mrl^`$Gg"Pm/521-C>ldl[&$aZ-6gmUAESdC"<mkJ[R4J_rn+E7O4Jf9]atEa!sU3OA]#XlrMJo,JrZ%5d2]d5Kt<MD^J>t`86-WGc'm0cgT?0g.!InTDh,_;?C7!-SC-B f9t$\^.0oSHA94BgE+A2)Ca^"&sN4aY-`fF_N`'<!^NUk[.05sj`2-7AO'WBAAP1.h--3,AA';bdbNhfL$p+p^!7Tdn:k V+oGCW]j[IHOC9Od!>8''4mTaq[2kH70 i+EJh<,N:0<@Z`dsBKA/E:$];\j-9O5#`\Y6.'F4+AAI*L >.+Aa"smg1e-;U%U)M/>o^#f3*la>+ E/j!4FcZM(9RbWR0'hE\*-A68[F_G?dIbeH!+cS<,-m6L^8Ffa)]!9>E;kkaW%rds,W+a6mDnhJ2E?DU'f0OBb[Oo&>"-\P2'Rc!Ls I0cE'nArkdfYsfo_`.74[rF` Hi:9a(?&:SprMXm4Z#nC>I4SZ3Zoq3E3207!e`N7pL]?ALII%EcE)UcAsE.W2Hp;H9f.6+, ghLDk,_;h T&AP("mHq/_[9kfk(L0+c_kI+X[b[n.99_:>$f.%.56=4%s9A%%'/"LZ^Q)EZe,i%eJmpGE?Ys+0$FUa@=fjAQl!/Q.CH2_%2AX^<_Y:3SJ]rcrXA$dP).gd([HQlTq=]p7/]!LO9*@=ca0/Z3@0FIMFf_siXZa@9.G&^+ C Fsf!VNRTJV4"sdYt1e`A8fG#/1shHkP&:Bo8g,r^['#Tg?tFsP%J''$2>C)+>P`r)'DP&/J95^P fLEpi4=G3)34qS:,XGEEiEqS$Qj^Zdh7D/7C"8KP&(1=We<URP`"(9Pbg@B9-_]NJ)^]ZiS^XdL3o 6ns+YqAs/7/c3+Wi,kVL6IioV4,5s\A-jfBCQXt.qR/JRlL9B:]=&[f0^A(L91H! Pj?F^B7M3R:So;X!PA@p0AmW:_R;T!OU=T=I% @ZS/4#E%;gF,<k>3^kEtL4TbtU?mk;.VSrCA$8d\08>K*hJib__TmH4e!?G<KqO6^Ys`b:?/A"h="9(m?NeJ\'A=6i*'R+G(<"4J$giO@R.dsT#icqri$&Yj 1X2L_EbfKJJDg[5=eaGDWt=A>5SN_49jl!&VAO^s"^ PQKL%5)aA [@#,S0O&p]=6,mKq=J,mAB.<#*(_eS ii#NK#p\H>Co*SBDXiV`"%;o^=4VaGiDdCsB$H@\[  FiZ.iALhM>=p0R8UoC&CRV_OUDI5@4>iJ,%'G=Skgt#hMR6H)Ka=91GU[ao9UJH0Ym]S:ZY!d,-1$1"ae].!Ao&h-`/L"ej3YYI.Ge(Qce.Gn*QrSaX7WtSP`PKoVMA;KN3/?YreI$!KB'/mi/ h^$W2`BjDB@9p_JIrqFTq22\`WQH:;")70d"di`KBZOp"<:%U6/-@@T@:KiYlANXit!UJGtk(.t]$C#o+k;:WA&DgiP+TR1r[W2n=KD.9,<_F>i6`85t/+(]s:7J?78q*>>7Q' (Gta[p"f`;AAsNQntj[<HcSFF"iT%Z,P]j/G4lXD3O,ABJ\L3N%PT8_[='i+QhC8A \.X9$Krtr0WPSG`"p8 tU'AJ#e([Gq21Or[em.EB,"-r'+:\t:ZmBb*&( kpA!:63RTsJLbATN`//D$WXRI7,UIpoJ+jDc`<1tVGpW$Pcr#OHRPs6hbZSTU=mkPVLAhL]>@*^q:UJ,G"`'&/)?BB3]4c1p%P,_% +/?^@oPQ1?7o+ppq"@$J+cK4!GY">?J1'-1fA_lNn/[rmG1,_j4oq62Y?^9Q11P0E5'0'3J+tnBlP^]e"0kN3Ekc1WonI9-qsMs@b-.'/AACX:FY190e GgVY!hZ+ Aa7V`Z_k0E865">AW=1Dk^,,nadpT?l,%$1UUUqnh51&M:W,(UFc8Knc0ULMJ`f8h]Pb><?T;qgM] pUNi?FA*HgPa*Ig6rC W*>T*i_Y$RHG5hsO 7bb gM/A5A'5 5,*;5S82DX%QmA5fgNi/1&P;q]dsNU41[#D2D^Z:M&[;0>b\:7jR*e* _H;m;@09TTsFcjAt-$H?DmP*]l<i`33Lth-ObZ#[_K:E1oBKA\U%ZRW/$HD3JrZ$M-%5!t<7.Z0]pM.75r+4gI;5rS?sXMr`\0Dms:P]2@-S@b7hF\ N\EOW*Djph-em`ak,Re(UkHPWM1`S@_8=pfcP8ZF.\sl9LfGbh6r!*fU Y@Hf?V<BLY49;#"?\^aaUV<$#)%"2a4O'aQ,IKl.n;^dEAqKdE4Z(HOgOB@!\-AG7!?sUlS$?.M)&TW25Kia=0F6!>DaNQ=><7L_aC4oAT*BE50p%_nI),^WUrm>77Ah65?7lQMn<"4@nc]oi3t-A5qp*BD@e'&XCij9#C.FZ6\dt?YRb+^2EJtNkB#o$)'-j*T;Y!\55BHQ"*"fMtP2[jgYr:N!ncG>:B^p=+AK+8_oOY8Gd/%R9]$3`o'aKE34?h>E9q%iIQM-+L46?T]4U7`fUoR!'Wekf._+*ED9<%CIS:^tD+/dd>0^3NWop?Inj>Nj[%&qpVWQ<<'dAhmO\pAECmd2l&?<e U#5.)HBCb1A-KcG/MVi8]>2 mDI:dVSc!3[<EGd*YLii!/6_M:1t8>Z`'!%dlD@8pAKZ8!mkb^^kWP[l.[7\C)Ut\hHaj,H;QPBdpohH]fdK?O.A,EX'5g-6 ZS?]! 3rTg@NE1_r9>p K>[;D9OjYkX&b1g4#fGP? @VHt"HUY@2Iso4nIZM6TA]&Uc]!nEHLj2[@dUd"(f(l!VOgneeni],`S)L:dL!&h2`!,$F,=5MZA4(5*0m%#/'iQY 7D&mN=2VB,19(_Rq]Df+Y!\=HGTK:1J?rkOLae^5`JbE9dah/X,k\]:A2<imn=MVE. M/HNTl8g$m;($GkqHs&f$HhGKOfe?+A)F:2^73<l9KSBWWr#R[/#JXY*;&'R`Kk/#o9B;rL?Aj6p8DIeFmGefh#KQA'@SL;>h.Gginn.j+Mb>EXl)Xsb[NNF"Bltp.U=0mq?THM0*nHSblADA&aHj#s#Tf13Jt4@!6NKoK(d5.TLh)9Zneh4)7i=N;Ns?BA5kc"=Hc7gUeX 9spSSBdPO(,JX%a]"Z_fAJ!:"Ds9frG$$lIrib./&@O%f(/`P6E`3T@e?Tgo]rbc*+5IM:H8"GN"j"Ti#37eB@"h44>+B"gCU)eXFRsTHp[V/&a QO:W<^A$_:tU<b4#) Vc[$+>[/0"2>T,YTRNY Sn_@0#m\3"cqBtQXY'?Ial2BW6nhIA\cUc=c B^!d<XT^L*`eK"'/$fD(;\=]/OUWNB>^W9^_-2_/qD&1#nst7C-&W03D>ah.%AU2(Je.AB.e#GZFFZRP_GPM#E dNaY 0VP1D8d.hL-%'UnXRtLI@YE"@q"QSJ5*<S6HM31gL;leT&,%CIVCA<0o!l%V+.>.<l_^.0p59j-c,/D(PGX];F20MbqZS/71H10Nb jUpp<,XgB: 3]?!;]nJs]66fbIH^W@Q'>1Z&LKison[,3VDs[^MEaS]Sn[35_.]M@DNso)?sOc94@$QJ&533m.$k%T[B?%5:!;D95dCA<g8R\ U\YU67Z/O)%6r\WpY?+3RN+$c] 91:cqN'9s[U?I3^bo3"Df-2+&Zp*=A$O3[kn#a>t"f8(M/,$_8@4Ng[TBACtPE600l;0IMBA`e;JD.6+d_!,C7X[3Ap5S+JkPT-T>@p*HfGgC8G8l$Gt&;j qFHG47U5rP;'A(8RiEp@-"gq85#djA?-M8U8l`BjW*7"o#3'\$dI"Da38TRHP=P=b^Wq0LaaA]%K'8Ykc<M'RE1.ZAK=cGBNZ5Q-ehe`7C/AZIBB565C!l^AsDa-_H!W:e9"//Q23bDZ<7<N;/8,s5\C;]dA!A6*5F]!R1^_(jVVN>HJZ0>RVokpZ#)k4 $Ta( E*Tc`dt_L%h2PhE.5Al1Qj%)HdAUd<e1Cdhid2]iBZ_)Y&3(Vs6!.kH\E?X;EloK*@peE%tn(n-8YnqG ]c3_ 7];d4;IWQ8\2NQDZ:TGXQA<7n,eM!=OH6N6Zd+`j&PR_??4^pH/Hk]n_*<!#RjQ_A((2N9Kq>@.S4R8'+U'p172,a1$&m'*N+8iMb:A&]<tDCi8/#cSI\a9V4ai5LalmGl^ogSk@o2VRqGG\[8,@&4;kt2O2%qgLmo=D q;O )14-B0dlr>JN+-=Ad,"N$NbM?d9GjD's27\E<@s&bG1?me7&qFJjE?g)-^fUf(SoF1K_\<l-"OTQH`-+4UJ_n`D=m8nTN_t'3(Rm!*A@p;=5oH"qq4B[O;qM]t1UF#Bpla1KBSX;K;<?]9ce_eYJ;\1'*I&lp.jHTAeLc9tI1g/cQf4D_mTP2_lsaRnesN;UcM%GQS/Ctest/sun/net/www/http/ChunkedInputStream/SCCS/s.test.txtaA@;pe?>W!jN@`lf3h*-Ud%8Ua!AkXGOL%U]+4Ol'!5J)M_!`X0/T1,N^(.SC77FpSiE_rZ^N*g5Ul:XIks/gDdZs70+kKtZ/sdg(l6mE"akc.1'.6) OI%<l`Ea/YCkJe%/+MrAndHi4!CXC>Xoka[%<;iI!q<$n0[X\X)sJ>:.4trHQF,< =UMci)!lr1H'8bAc_m\8W7C0[fP`^sZU0W?$$.%XAB5G<%JTq#0L7OC#F"3Lb#eC?XB6:[2%PM;S+e6!8p[lA*QK7Ci6E)FZNRk'42FmIK"7$A NL!DG0!ih`'L'-@jH*PF0+^e$4336K>LoV!'YRt+!IpKM5o7&]JRKrL  qaLj\W`;_NT >)t?;[?')A\^oa518(VaT5ifW7i2_DFA=.XE-R%Y+TWiZAQ_**DS@<6]AtYN3qs=;"t+ni@$pS;*K)6BAta'lcX6kMF2Z:H:<sDr!kI2UsDG8"e&>].7)+*EOFhSH4S;R7:QU`N>c.S9B*o6^F01lSo\/NX3nd:7>9Nn0! 1Jm7<hl`RU;.M:_j%0I8 UQ"L<++5*<OgN2i&ckKCBMBP`(i<rapC'm;/dces:fHsZ"pn;n_R]e!FDA\Y_1CZ_j8_ONkb3AJGAO1)elqE_ZPp8E0Cn!dGq#hqH[gf:t1=al_H#OX.BS0)`te92e0:.1m[nN`/1Fd#c3'6J(7eCf8g^$ttjOKk'fiV?&mR%jHYc[teB#73Gp JFp<a,K3._$NBH8i&<?8dRR^?jh*$3?S'.kmCi_N`4'_gLkJ/Ag#gl&3L<i('OhGXmgsC*?$7*EJN('mD2LM27N9geZ[-nAb\&:rGJ;*+h6C!tp$Ys("dEZUT3T.79sh"%Loo[c3ajg1SJ1NVnZsd/ HoFS(eq+\/bI.&ftd*gd[,#:;`Z%<M.:4&l1&aY2?'_A90V^ahK8W1P!*CtA:JQ$L417:&]g;nnfo\`de080A!dBWZ%OZa^1-@&Vf=(4OSm'<XVgL&OUi[&ci(R'<G0iX&V3.l.a+D]'p,cJ8El/8A%_8o)#3G#&F88V1WZ-)=m.D<CGCrNMG[CB,m2<\1%6BV10q46LoQ+8`LBQi[_sP]5@cf"=/3]]0$&+3q0pF([9(%bA#mm]fR%"$,Y$T%JR4T]^p=&e5r'<H"ra,j5T W$opW:i<GJ)^6s2'oE-W'fiPn`aIU*@G&KSbM*NKAeFjf$I83:X)tL*6\4(QjqO"F[akAH];)DO&7rETrNsR_MRBhNM>c8X$<5`jQ9,r;qNsognA[a*D2sp5:J<P#?=K<pO3XA>lS@D QI+phUn!m(;kKD,2k+b`Wh\M3+1TY(, mAs;!2;NTN.U^ /L2%D^'L[QT2Q[;4OJqK]Ck7E[o2IM7CXBLW*m1?#s$* H"MR[3R:[/.gC\[T!`2h0oWM]*&K)&Z,Kh(JB1&.eHq!N[M[AA$"Ee"IC1\:j7:DPn/h):XZM\OPG)o],.9]NghLT$DA#5Cl+I# V%t[!l9GmT;)8AOiFEXoL^(2'AVZMN#>0;9L?,JF(gifpJ_*pOHQ3o0:dC>aAU=kJnrVq_:;m5r9BJ5Y)df/`3nlE-6e:^i!!7@!b&&cK24pdA]mdr(%hi@YfJD1YJZ(Ddrj08G:J$iR%o\o@4aVPjB0h59$ek;]W)hK1B1-(^=.gD^<1Hgl8LmF9M*e:B5`Zf9!)IH%8(l +VXME\Bb>IRe8JEQ) XNm9A8j5.Doi^+%c&l;N$LXq4]U/fkm$0$;r.q7aX3)I\b[`RhVg\&@]Q.n/>g 70`Ugc7pRQ*LplB&QOro5!!g@8HMZB7@,8RtoC01JED6o5:l_/e'Q(7hal>EiWOh)`KnQh+h?5r912!?'r5'b+(Y,[Q'#='!H\( _`CBR/d;`6AUDN:%d)@n`Ag[,#mPGYWrZ]7?(NRG'Cl9$oCS@^WW8fL#po4`[U7&;&#MQ4l9T.Pr902kA!LQ<N+o4/=.N[=@dpWJXQ(U8 ks)70(nRiF&HE<1<[YU9Ef/ 4+W:0o4]OUs%@tWD!+Xe`%CE:J9;As:KGch+ORBct/"^#oRJiU(*iYS`%]_M;L#8f$N!*,i4DD3ed'P_]VAg4 oQ8QeV.h4t(=':Oc,JYWD\Y"?f1ML^)$oh@k[O;AjZ:Qp[\/LKUH9M1?N`/J"?Kih(RN7J.$.]Arg5n;_M8;>!A026pHaLYmq2=C"A%pr1rIoJN:ZnX5ejVhokNR_#X;5h&]m&_<H) f,#*!tAX1%mX]W(\%!('#QAFpP/nAi7U8Z$"3i:s"2\a-f r7D])pAqsO,JJfT9PM0f$`96Vce6jT_k(<Lj#$$=G\U3\gS1A.9=K=#\+U.;SY)>Ckkb39/GjZkTm)8VkLZHmj5%UJ#G2ngHtb([`WTN$Q+33HbF]qfKqUmRZ3H$m9l6*G06>+h g^<fc0`X7Y_\aNE]]X!`\pTN9=t:br\LS+kiB7QJV=NV[+E8H<,n\B,*N4d+@2ne+A@ )fq4\\NZcMne*\a%6hFY='!%ZOcneid>`NWdnW*Cg4kkkteOf*aOTRrN-:\e#%2m^87^1[J9T\#&ASQI9[O6gha2]jqa Id?:@^8]ANc>@*G&.(W!%J0?U\FJIrV&_CKVR))Gs@H=0I4<i-`B<OGk)K6L*"Z;MYqA+n5,0Sb@P5VLoGcM+/%\_c%-+B9,@+pa%R\/GLC2 _'cH/oj3lAP8lDp2?C.X2.9Vh05c@K8m3/:%$XI%i.1jr`8(rRLm<KK9C=5>f]-MhcM';9"l;L>dm-)P9fUJU@G*`SE?AVGn>AkA &gtCe`Q_-Y`I@AZtkJq!oD\aIZ5H(X;g<O5U]Z\hpOjksfb aKpH>9K2fds^;SA%_J"<dnF._00$)+VG:IR:rUNYf*?e\0*KBfR2beA&JnC7n^(b[*g'ZV^Ah70:!+*UO?pAPZJ A82GEHfAkI%f=5*?`,-<Z+*@k]F3=-<O4lmie(C\:#n-OX#+-l3ENgb3W=88A88&IhM?H<5#5:r?r2f8+WqQ?B@*rUV=DW;<ARrQ\Y)TCX(j,rPW8T) PW0_h.b:,&>Eo*"F+F41H,KleCP717"L69Z%5(Ah*j%:q?HH.maa@to2VqoQIm!5CoXk&"Akk>%/['&bP\X']n-A.)q$1OA_9C4AqpW%f`U-PrC< M %6DqGB<QWm7X@O!flCOt_B;2lmK!KgjG*'Z`_.:6_9k:-"ZV?+KZfg$<EYIV<'s"&N5<m6ok"iFNPZ3WJA1AJ*A]#Rj&pC=hQ*?2PX7Og1<B7_>\_bYLtdAd)L$+4'd+6K/.:ANU.5nk<5$9fSM+,PIESS]a'Fn"=*qg5PO-=bCW7EhL6/1.=hgF.JkE_GPMLs7/2WhW#ZYGLY\Y 'UTr;M7Z[\e:JIEAEjr nisP*ZAD%%X5<U^UZAQthgV]=YG:R>bLSMC`_0Vg>hbD]l@8Wj,;CX(K&3XT%tFR<>F)'q*#R[bcS7Rke'E>_6IV[g83]4@QT,&,. ^7K>nL=N'[,Ka`2s4gerT?c1>+%+T9E6_""$NjT-]_A:C,\O!<H95nQQG>N)oLJN+cIh>7M9P;I8f7L:FJ`h[$88Z#".tae"1(Kk12CWL:mUi@[/R^6[Fl?`m89[Q'7MIKRtbVtq?jZOWADLb)5LfY9NDQlo[I'jbtm>1#s;n'F)J\B&X$T!9sH@4@gBL"KZZ3lpNV*pm%E,i]i5PQY]K[8M8A02L]4.P_8!6oBbT1e4U9s+LmG9BX1a1SoTJ!RArs-M+4oHkM kmbd?dm^IE$`>fCid0I^j_FA6VAr11+Grl$h=>6ptU>V.D$-Go<;AF@[>3j)B^`8scNE>>Mn-B>,d"H6>3]6_[`pbI Tli@StiR;]&^BmL(.O&<D$)U'*n7+D]7<Q :G`sMgokVOLI[nq#W 6D4.1%<PE/@nAYlgm& 3hAt_NHU&NVZefQREB6s),R:I% d_;.TZJdm3T@A<^1 >ll 7T:H4n21BRe?`b,Y9@G=BC`3%/f8^#S]K,AJ]Cd>%tA?@JhO+3jjb6mg.[lFKH_N54JI^7n+.R9()PAAj',,kea\.,*heik"i@KE_Wd,=KmhG]")2:_[JOp,G[C]tGs-d=!_7L_p<MA5,rL]jb*?p1cq:S$NLHAn)eMOLqiI\PpeUhSl(G^-4H`WVCG<7]Vh4i!U_Z>b\'kZf$1I'2"0NlS5XXH\hW0+tL6tIa8gWqDQa6SWil*jk4V31KfU#h!L-(2kYC=6RZSMKj.M&W44@Wikh*,8+A/k=b8h5/*O^Ei T.X=b?\bmFe4p =Y\%/5Ad:(39>AWP#ASmINmgl"gP8&^icBi;B?3,qR,UdC*COaV^0r9^j'J/g1'^k gr`W+8\reRBgta9P,Tao#^njl!.aR"nT:YQMp[+;sLi9m?"h, J.7VpH.?LB&'75J%9JoR&iS@9[rK=UldXCCraQCD_O("f>ahCTF/-Pq,e*QC7HO%sAF9-@XEV5QAft?fZ+]j6If9?D/*Xq,>H]8qjGaZ,4coEai+qPAnrsoL5!OCPl#OQ2Qj9SNTT5r=@-ghrL#+Z?)f9Cn\^+VT4['%"0Apm \ajn%s;She/E2cGUe6S7HifFtC\C'f$Drqhgn6BknpXP`&%lOi=t-aD\j.X/SAW)7AIZG&UWi_(%A! I9pLp8hgsS>;Q;rV5oG9dLDI1=[E9K19`__]/68q4[nWZ+J3Y0X Xop\8bDX.*#el,[HVfpa#`@JL-`dp)[Tk#.:sZG[J>9<e\W=5V,lnp4i,<g_cmqV2O;)W5R`64U^=Ad`f>P$:LU$DZ--9Sk;"PMja,,b+r*i@qMY*07mWpi@@c*@ G'%setr`Oo i$*<)K6UY/`X<tP2qM,;.An2aS6=$B86<"3\3!731(Y<#tL*X0[B+#BEn%F6lHP7/K$p6 bH.PBt=V"Hj!-T_ 6@Z=drG0j5djnd'BD,"*5],!!W[4epUO)E7\jdeYUbPAVq'tY<R:EjX0/EnMLIUffM0"TB^$XPVSGNnU5K9XJs-4JnEsr`@4-7931N%+\gAh*>\3./4W,<S/RRGEA5o)#Z6MSgW<0TQ&V7f;*dNpn01YprAAPoFH=&1Ta5([9[Q8#D)+Xq)AAqE+V(Lto<RfAJ,e4/"RCUgIcY&g,:IiCP&i]?p>cg])P.^>ENU4ZbY,p08=b9KW;06emM0r2D]rk7*eq>]UYAQC)68bl4>opCE\@Cia?Yjh'DNB5e!*%JLf=/:.eGj+P4?DC_Om=IFNsJ`Q,R`E9*te+:d6sR8O$k?=rhKA_+]7Z]$]6aNKc[mmE,:FtHn"Z[SU`r.E6a;'n` .6L1QO(!JhXaMIO@+Qsq)'+DD-5?B4d$!Oqb!;,%/c=+I5tW,Oj<^a?%TD:r%f_9U]1t5js[JC>f&O_cV"rIgiJs^,mD?<?a#[6G(U4b@q`T#6eJ6.Ab!M3#lmO?hsEZL*(dkZ]c2=tLk(,oE6jHZt&N=UMKf'-,$$)6 #7**I>g(;(_GAV)i\M)[#kW''Ur!O*kP57AnnHY7[47,R[&9SbcXW*BVr;=mr8+_U,nUr0I_r^@ br^=pAgHqka3BEOph67]1U#"j3567IZTC*`oGdO21Q3l/V:m7$KdVE;bV28[Z#G.F^&cISNhZ82.emT>oY/^rs.//X=<$%]BB"528)tTn4ETK _5C_IZm;"&."APR@,;=JGk6"o.[?<%Tq4S+9WO,Y:aB#0J<DfKk(5b#5sT<s>LjW0#Sm(\nr`o/sP3Ql%&%j&<>doic^smX8+27 '4\1M h_0q6)99eo^tAm^GH!C'QF`e5r:ns#*bFm7-:1 ](B`E2trob<6e`^FeI\XUA9kMIt0'M5)T_IoX5pN`2C*E#\2AcR-Ns<Np*/%X WAd`q_JP_gEEM/1(Do<C8XgY#Dp<Xm/%LQ"81F5=N2ip?Wgm>d+ pqo5=;0JsKDQh+'kN'%;"o%:ChHIN$R(KD5)A7Jc[eHBs'!C1>3m(-fGVYj$ZiX/Q7HArA'Mn;8r.W]i6m8/f,>4>XB@MJ!Io(o'T8A@s(?h`KbIGDOkMW_XCee:lL;\#@1I:YO8,p&dMm]#h,*B[o;-E%qUt_O00%l[_BkDt,Wkl8g\6@:S#a302_O>dZ>*>8)Sat@-\/Z)ds3.<cK]r=m?rMJRU//=EbSR$cY=SD2([/I/X\8,[noB[3;ors H$FV/;4C":NeS_0Q=R$^cai6:+r^/&Yl?BQV,?edHXV]5IkLG/CFp[19UpnD9sA=ALs3&8WJH-Y*r>t6]-a:eLO/0_0tPT-Yen9(*eGfRT@F")SfYnV,$?L>%q,A7NT=/k'oh.kI9f.4kQK S(%_X%`:"%g0/]-iEm&[U\ARk8N+U3bl4(Z]G$9_d'hbSoK#bYreD-cQ"]W1T<lE#l1]>26F@^WsI QV,cpI.<WPTP<L0AWn,X.8N826l+S`=o^_M"<<ALZA/7J`TA+CmW%=Hpp#G.LQQ7,-+d\X_;XKsIh:V;?^EJ[CgDO=W^d5[HJX^sf<MV&9^EGckgbcj>iGi0/^_H5W^PS<eaIa+!`I#',0+8EG_45qFL6`VqR<?0'<+9K#6@b1iV5lT=n0;")M_As1G#6s;+SNtAoM"@po5<'RV))KZnbo#=h7%Kt1C9glfp7QdoYlP#O5<ne4nA`qaYG(p6W#-<'koFtAo$aZ/iWiDlbLFj)hl57(eVgAqV:r\VX@J7?Q2dK#4JmaK6e[AKpS\:Yc=Wm=Qc*a+n=HP$8Rca8V4""'\Xqk]Z-(ER'AQhAgs'qL4b#R4#dfJ9ZI[Ml^+ V5Sgj&!)!e"R'qLoig$a+22Xg$%Ha]aIbfPgUCH/Of>etF:UY-Q4GMPIg:1N-Ol;P#iQo3i4CE.]eYi!b.HPqP8?8rqMK&)%ltAtt7I[2Rc,.F3()Il`)9B[FH0NMiF"imOiBAAQm??^25+I6r6eonS@9&nM5t#5HMGTm&V?EMn(#^6B(X%X_4*o&["<gpegC;NPVl<q!n^mh9(G;!9A44i$aG B8._?n.9Kmt_Zj3VmR2>iS<lhfLWQ"r\(S.,[FedA P[:eI.[7%1=F9feY+/-pqX451L:lO'FDF99QQr3 N?7)e8n=JR*B9fd'CSUR],Qm`e@9#bgTe$TNn;aV6#'!Fl?D%QIa&S7'dg,JOJDlp@ZBl;Q#_-Tg";T. AT#NRW;.50QJIm9aZglf5YlG+?*"h7hZ)^Mp $`9&<2X_i)"snl(JEW0[4)D9A*/O].#e!*V`YXIe<;[*W !UY6+;+gMZ*Va^Ik&Q;_`Tj+S9S2b86$*Na;?ial(-5HWQA'T;rp/kbE/#9>mAC77R<pmk,dTJbl*l+&Dt4*$5l+L5Kd@W=@@r)"YYeK)RQhDhAWtU;jBHjg<n+XE(-4#rZ/G*/Ykp\nE;kb7JZ WdR86< 8.V=_O<HcE8cdW!\\&VFIM=K9)ZJ37I<2SNB,K`&9FOIdcZR6/@-Ykdb-hXdSi,5[#gb(t6Nc>7$h<(k9T(XHbMA7/&C:WHXsLIsj:_JJ*Pjpe$sh@tIp:F*]"#H8KFR=QiEorEFC2VZhO'(\4^C9qN<UQIrXifg19elc4/Ebq;8^U_o9Xp2_f(SMKRC<8Y]#)eI':0-CiAtjdVV#kZ%!3Ja3UftM%_[FWt_ =*X7()b^A7B]M]dog.cq;b56+MLVUB,fO0<,>Qh,rjGm8[JAmGAC0V@=G;mMLn%Va\ZK>niK0tYo9E7\)kK\U<#6(oX1Ngcf?Mo;dB`lpDI9fVs2>#Hf>LXnq7PtYp[8>:NaCgFI+Z@#As?kokS9%.00\jN"UP+F9*5dQ:ph\)b]Lr*Z:E)bkl q8k1L3mKlc\70&ZNfp7Xq&3]dNg@[T3&/p,id;XI54:&`jOVh]U"Gd4Y"gq5)\n4f!TN!A#lCG:4NV< ,%p`b<-4q\dt^n8b&lpgM+dc/HXAsPgFABAakW!5h38tHVne0prOK@GV+Dh;.A1#;WF5Pb &)A`Has6C#0[TASJW&\8JYpDTHK3_DE1RTlPjRrcm;G&I88C2CrFY'Lf;8c&sr&pBrTSsN-&LTj%\-ct[k^\Ro8JPP% J;Pg]p&8C7`CRLg:cd+T=L*p9VD+'[R$EPM"iniN=s(57WT0eU$K:l,;rATGAKKE39d=`!N-VEA&5[b!MH?;.kKP"XrkJKa-\kZ[SLD5VO,Z+J_lNp@2\HE6^^NO%l%+D0^c9>j6D<\'V;;6[8hd4)2r@\">!pAjXRrKW_:hPT*039!&)D^slWa8AVt35M?6^?8)XTqI*9O9$SGsX!cbr@t!.FSnIGf"_TA(FO)_DGr?Cm"*'hhOkF)C2fiNoDP8YCIkA!l0gOG8bCXsn.F'3=9#(A#r@K@Uq51k=@_,Qmf4;^p7XqnGH=0h#]p](HJ?Xj[>r>?U-4ZH_iR3c;LenPcIF/4\*.ORidj\:Amc]oJ.XFN-<es"F#Q3IA9>aNP")GnN[r.A9qFK;Uc;f<$%X>U+eU]\#pj=Z hqWM:MTq$/&N;eS&<8TLd:&Ab*r$I`^Tjo9Vr=O)->.eWoX67"jKGNfFA%?q-'EK=8g'_3k:PMOEKE66cTU99+#(D PREH#Xer)2ZO_:4H:'/d Hp!I)nqOrglfos*[lJ#rR&]ShTa)$W;ZKenVk`)S[8@?B*'3dHLh$9&h*XmqI]Vk#@AZ"RV8n(tC#LlbRUJ?(hjnf)ZtlUY[ sgHsHKC%1nREJFq+@D.nb4aA!9pS?c$#$-DA*6GQ568LTrtQOT79!lk2d F<V \=VL),,A*r7Z`\M8Tt-h6b"kK0iYt<3jNM1@,16$2'fZS#6XF?)@U 0paO$6SGHL?aq:nOf1 F=\]]8HI1qMI^MVRTRK8:rAMciqAYgWp-;V<*eim;N=!c,ICQf.5jD(U*Q"s9mbb +kppVO`fBYCr%5DOEt?.=8dQ,^JA)po"`]Aoc&dVOHI"D[2ZQ&4LUl:-OA-LG.k^Yf0cfJJP)jBF]0;QV_c\^J[AbN6.t,*Ya"nlm,m%$:i(LURoO=R7C=*pS=!=:El3k0PA:!Q2YLAiNd3OhDTX>Po5@"s!WY7q`=s1(Q^S90M#2I/3pHgkr=3IlK% 1r\_'N\1cEU!;668C<oAKN*1JToC/'IakSWG2lc`DA5E ^eL6(#RcT3"c,Jo5EJ&(9hWoq.];E;6#Hh\l5*es\7r5h`O*&,VFX>"1-W-JJErl:VNKbji+2SUDcdH0\3kh>c26a1h#6$8AV3dCAk<5EbS1Z 4`1CE7a7ELnOsLFXTVF9S =N$7b4;a&,7cUY2hr*P]nX06GrASL`<\03eZ*[lG`_k`i);at3041D"Q$`9L]YVZ)Im)IX<\62,DmYMR\HS"t?]o1:NBtH=[:>b#K&Y,$Qa /sl][0 &?pbqX>nU?)1#?jkC0)^$T;OIEGAQ6RT>Z2+')DgKA232na)2586_o1=A>?mBk.9\J@isKbA6//kpEdDbA]pCoK$f!%#?`e;Y-;d[<`&+=XS\&VAoaFZWlAJ#N\)4E=0tMCMKXk$6 Qd<#5@rNCh%7bQeAke(c)Vi0bEG/"8`maPqA!RC6D1 ZH8ME@A_[flBH_CGObF\AAL];j<a$\sCpRQXhFHJ=+IQ'Ap`NnY?@dpaXiO6'V'9=]XA:A^a@dD&9$;GmjRT <5BcG=72X#SW_-jm8NZo *bf$HDJT<F99b[a`]5`Aqt$%lr0[-IGP1m<L1tElo@J567#/\[)q9J!$q0RcS:48tfhg\?8I9B)bd)qqZo-;O$?! GR6O X7E[OqO++"X2oFnYr5AZEFqSNi!MAAJ4>_@Wkf?hM25%P6&fg3/0&ZQYE4(ABStJ'qKG&=YQ"A=esLc<W!hKDoiHFYa3?9]",+Q'qDf\n'qF1*Y3q%.C;,es+'SXd^dCto,X'<ZEel$Q1kos$a(n$G\Iq[].13;`PA4'qEA?X8o !Nn0!e5D<`m&GpQf?AL%/iV\WZtgl4jrC=(5eOQ(TAS9rj?5%,]j3>a`BO5b\!,Cs%U5WTM@Xe@59in0#Wnl2CGU/f(I.nnh8d9nL:.ha],dL%!O&(;Nq5MR]r<pR\#Sld##DF;Z[sJ9eGCe1\I&V&qCqEh8h*ttJpT5X2eJEi(Kf;)JQ`%AWI4g/9.*=?H?2@3-:$BNSWXGXdX1)$-fNk/7q72%GgVXc?7.%-7` Cg2ksnoVOp#K0K1'N*1Die>N:/Z;ga-Rd_JjKB)*`_4T'2AY=IC:d./8@WSU1) [8s3E[W#gm#Y]g4;[r>XD`LY)lAF4[TCgf$-_4' 9MH"I=N+!+g4q:;4m9WI.n/0dm?!6mW,,C==\O0^I"PPLZq2b^J$q?gQG-16I<rW'6]$dII283 UUW7V6D'[Vc)la!]N:Ym*K'^0$U]RH_N,U:]fChQQ;\"8\A.Z"\1-!mP#3P"6TY3:Q]6Dr:&6q:N9lYU2$QEtY]fR3aCR5P^#hO4:X#--91cW8Z96HVZ$A8P'm9p,8-2_R-Wsh2Ckf@4+@Ys(UoK@*CE(U":0=1OA_.Rqn<taYeNB30THNp#c-7\ZZSdGK>WAdHt5a>4J/_ls R#6\J5$X]o%<%'"3 `A*]=0>+@dhpC!UWb>_+;@E;ka<HZKR8T*,"<7J060U">\a h9Y9M"7Z_IET>)L k$d<W#+Y-)D,lI'Yp;_ACgMEQmhQWtn!$)&9m(F4VZDP0nWM,;dqgGt,rFM!A[#JCK!gfSE(h1im]f9lW7RVa<)(th@re]`/:Cgs>bAaL9]AM>As=oO(Pc-D5@p#<'NM[JQqZT[P=BLtscn*t6C+EYZ_fh0QSCk$LI0(a&`:jtpm6^%=L?8?]\F"P"C](I*(^fSr'$[gatV&o:&k?m^:PMi.f?//`>jOF%`N/ 7-7N>d(R5l"q8=<L2b=?Em0OkSR.3"\rG:o50,sp0GhRrS$)e%Af1^11B)^ER^@mjZA2%`/T]0Yq<A8`;XtM[+[,\S8"[\RLH/tc[<%6c mrAN"CkL=bVE(M';(5.Y&76diNr<PDD1ik*]7sprI) ] Pa /l.@O0Bt9-G'N[I(QGYdRt3&Gs<QgCJQ'DU\OZ$[8NVro_<T"8dt=Ba&\"MjJT[&ZMZ@'7 sQ.bMcf0trcH],A _r^A$p/*7\mZP"*id I>D^C0(-M&tddJCYL:UdMj:pZPmi$_;/0cb7H/1?AlmR(S62#F"e,&CpSQO[m9[-,&dal@DWZ.7+H!;etAsatJpZg,i*okI,S;8Ef`rj$F-N\'%=DM\;$jk (Wg7!2531OQ;Sj$^j^m0jU%(l]j-e$RGirG"po^71[Ie9h+(OLAU9a D4e/HbsAn<P,5@RG'M:#g/eVa@<@L0,(7)X7<sVT&,R!0V*3c%Z8tkS._Io(Cp^)Tah`r^6FdQ T8p3fXjBQ82bbqh8FNC`L[i:O8CX#c7&NA5p%Ph7Fj=Jg4eTV4_8^fBm.:L7Cqqb^>e.d%SN;;goAQ1_`SV 'N*3#kBs 'TfNp`_JsMp$VYrcpIG9C+pV7[j4d,5N^\EK.q1ff!AU9AQ$44B8T6Hg=T-E%"VjgbM%dq d@13`UgbS?#6I$pdl=Qb"p1;A-Q]0Ro]bA "k&5G(8>0`#6)JtrC;_hdrU@CBBrb'%$C=ohkmZ0Q[\1a4A'8l)nA&o0#<TM1aXEGm9.%BqO^dP(H&?q%?'FKQ&Y0g];8,Y-5c"f<1V.t(%#H:;ek!imGA"`(k8+.ak^_CUl(T(eZ@^;sf0!saTpj)5peDp?ZE8?S>n'=3!iZCh-<:f'ZOb0<f&)cZr,!/r-]^I<cQd7FfbkOOQcmX@p`^^4;%OKtX<pLK 7s*r3W)kWFDn^J sjIQ4/^Zj=&7&Z:\&+\^%4-5bD^siO^5:&F9d'I[im#fMPDHhVJJTpJ/sAabPtV85*Qt2`_!2GePMb.g7E+`D6)]:dFAYm)>;C&mAF\[7(f7=KfAhpjlM7RT)%=jrK%C&I8J2&E8,+c"mag3<rUK6+FR@M'=@L5g.t#$k9Agjd^(-I@C7Z'!e!''k`[Nl'km5P;;#i"OfWWtNVPKpZ+6QS%\3l;Ot;d+NM,=h#Nn:&]UFP2n0_>"re'""-#rrA?O _0G;KM2gQo`HheqqRGAmAm7"I3r2WYc'eeioojXT"V!hZ3`D\Etrgo-O,VaX8UU_#7GiCgsXV%-PK1(JSm7R'&eN$kQ "#kUArkU4lS_VQ;rVsiQ &@A`csf1E`*+EjNC59F[V\'o0$#Rhbs)><^/Q^/bqL3Z3k. [Umki)clEnQN\. s]S+8ZF0?MBlAqgC\[o7F(1WQ CkHB@F>BU2f2Z>AZ694KkP4q;tkSKaoF\RJcB(+-92"7=6Q_*$'[h>e9W-2,'"E#:D .TqXm'"HeM?]3-jc*(T *QET<^]bb3m-P Y#-\Ql'WL\X5r: H_BjbLsb9a4N"Eb/Em)"hc2XLIKrp.QIXGDL.n*X5A6:Iob=-6k;SAQ_N'>e#C<DAeL=8_GZQTE*brM,-o&FALgF@G^i+HRLB)A=H,.(U5tW_"F`>\G?BtOAd%r'H8aX7%5C.5iR.`,Ng0CEKL6_:=UQ7F])d6r(Vo,^O6[I. IJC(Z$kS-sBWMT(mRG*::NS0$Oo!1O<e!7hE:R9hJY6IE?as"^YBI#/Cp'9YGW`V*c>`IO,&)k%lQeG4&oQ*2\aPM8]Fka(/AH508dooZB@\\I\5;iGUNH^;S]NpcJZ>j!EF>NGe<i!2Fr&"T\cMiC@K-h2\g^pTTPl%X3Q#2%t7H/cBGACb/q%>rU>On@+&d"5;;Lt2A=N;$S67l*ZT@Q%7A&t&c[&04&C]e3M;+!:k&ZpA`B!oT$CJ:IJ@Zd>ki/!2_-9/'mki_alD bhQB,nUVA#7dW^8EB8?R[o.<B^,*,^7%lf.LEp-pHD>T(A5E-?80 DSoTFEi0<plbV]/C]#gTHPoP3.+5kF/KeAOUeW>4?%h1h$HL$L-L=nTrHlLAj;q^A;lL1E\XL'p/B5/@9orORMon>Gmd+6B8_r='+MABWfsqL:ipbmcc[lY!A#^f;AS\(\;inAR$^FTn<6%'<rGA KY]PqQ(B CG8km(^4*FaI#9/AX5dqWkn:)DM5eNn.iLnl>P3dckS&]nV/q-mpOIgF-6\kriesO&TM;<HBX.]iUlX'D^.Yn,HQRL08N9l7)9F$,hop&[:;8e<`k4."P?Y,l8C$Ql"hCsEa-8;e!n':))D_+qCBYZPDk0hci5ZoNKr$t5=*U[p2gr^\Fo[R.]T;U7V7''2&N*3KSFA:`3NcmBr %A"%4?AACV9YH`H1p]3S]Xk%npQMk/4%)t= "rRRH@o)9g_Akhh>B9hX.[d[>qbd-J[Bmfbd_/j(OVKX83N8Df"4JX^:CH`\fT4,')p$T#0XGfAqY`i]/rm7"PNQ[e6J1OD#LH$QYMMqH1%QL.[tW $etq=r$F=YA^L>DNj4Y.?_C?+2WppMb^:j!.=gl1/<Pc"V+0mjfYF_<m!0t\N`k[kSTP:Aha n/<3#"2[Wi'^?.r:I@!Y8P< 7seCS0OBZ9](A5?s)Gal-3UpJQ**nj.`b^1O/f:*HG1DoD?:36F:*D0U];^Eg+ PR(D)['@Y;0QT4L>:?pBa6#tZltcS)R58;MR09A#p!Rm%RDaTT^"o@-C@*%<;)q%/4.W)nB7^SrWMB3l>$3`UfoUkbgRW>FGK$M7c:gV6G4cWcj(+&BXnc]6Tp+QP%.RW^'-d3Pq! U%l'j26D41c H*(gS3NiQIsa]$Ion p8H3nr*>A^qpl.W<mL*:J.4RE@\g`HXc)go QcYk.T"QRlV9XA@N"ei l=HN</:l,m>[6)\-o+RU]Ydn%s.ON3@Ws`O1<TUEH]Vc2erbp.GYs"B'0K4__8YpA=E6+R1Z.Ad27;$!T_L\#7d%;4c-5T:D"!4h7koX+m2,teAq/H<]bBH&@.'hi.g8J[?o1E.T ^$::r:t&V'oE`)F$;jbOnA24MY2Q59ms5qYI`Ai`P&]'V]fhmi6KT&ZO:1P&eeUZEK+ 9\-00jsAegg\+0;E+F)_A*ptF,?,/dVZ'FW>*qj/B5AVF4W/-1!ib\(B9@a^gIpW;e96\E*d0'bmpb]\1)22,D(jn1<Qme[^])fZCeD>X?ZEglE[U[9;%D^n7Ad_P7)iAXj@tOFI[@4=>>%[g87r8T3+Pt<)4)5Hh>ODI>'?5@APJcV&bXH*AY`<T$(Rs)a.+K"EHpJ^-Q=1pk mj%](g\9<>#L<4`0ef;N?<EECbn]Ub`W5%HA?):HA+_+cRP7#fimbL\e5SsnXN'Md*m&1#X%1?d+D6pNE`J21s*Son<O)i'jcnCKA$("p+%ZBL3-+:L=1Uhi$oP60JN)T@Q<AM7]Tss+q_V.d+GjYG@[9+D!G+`jS6_sHq]M-acLOb3+*!_gqp;\5Yo/P"joMkrZh)L5fA0W-_^Q"&^lDi:aWef?+d2p>aC1 P*76q!4M&T3T-/A$njY]p"KSCla\=(UAaWKAi@>iViK+" `]F-EJk2b&_:6OZo9rJ^!tWW/OFNC<Y?I1bK5o1N1QX8]iAM>N<3lF ES=MTpc<kpe1G32)[*p`'At?J> S-AnSDq0'Qf2,.)r5q!MQd03c8g=VCR:)CEe[2HVNg*7p'+Bp3^i#3HjDQ(7i#!!XSAmt 4P-K;,!k9iJ ijHq4k]LZ %KNOA+kAN/^X1fJ"2I,0#<1mlMX59[XUg7ZEm,$GRW\L%LW>Go/qCES.A-0D/fBHd3R("7&n5[Vi;&q)4Rt)js+YEJg^0 &\V9A"KD&8r6t-@=$>! (2aNc:5+I02R3qS9Y n/FBP%$;&T8Tc]_X6p7(;*D)m5<#b Noia*7V>Wha)9/Z2i VW;S"8h=LsYpW;%_.iM3=#g`L][H1rEKIPHVV->?):`8!*Kr2<f)Js4rEP9p>Tl?hq!LQ;\4=rAfL*Aa"RgH1_lR&S?F5HAjP&T0PIg4XLAYRAh [a1Q+lkSA [("*1BWR+$W+i&G9q1][oPdi\' V_1[kqL0K3ID 3h.MCX@V<8Q3PDP4K@=]ob7A)cI*6YOkn\"R=o2@2rXaZ=h&&8SLr'2?8ht `2Ygj?Td,lsoe`b9c8hMpQX&,:o=A``PAX_W;(+4)UmgC.k%k1`?HfBg(.l4%r2 b;s)4q=/kU07;*Z!qJ/3_n$j9"=@p<([2LfI7M`##'[*meTIHG%AZCXWg\6SUo]>aLFk'&#RA5n:oZ,2raU7dIE)l/eo6S<6^EL+tZ*dQ^@m.nr6F`-;sX'@'hOcoT +D)Sgg(\5B/7%-ckN^1gB7<M-*YI([hqT]s^4L7+,6<q%`aZk[8M.DOX[XBA3q350ViQ4nAsbS8t;X>7WogW&+=4:f"d."r)paXl3>HBFX6XEGjLJ3*ChXJ<s&`2oCRXeDTQY[OLD8`t-H\f@\1t=cnB =0PkQb:FM4tc2tLJ!OBR#VU+#mS1GI:Kb2L%Q`"*Q55c5H8-VnAB9'>S)k.IXhHZXITitshjDD;mSU43qBRH!,MK$AD-&H 2A"H?q!dj^rZ9= \TYg;[G`SU/@>A`0n;(a@Z/2O>^1=5);qCFnM*3EnN-rSQC ;"+$BK: ?ZjaHJ,FCq>R@cBhXG6\Nf?Yt^99f!pI2e]S1*\p)78"LIY;AY+f5%hU`s:heEq;At/0?^2n\V&=pP5/n`KPVO9UFmNTgdZ[ZgVA`\ILfOfA/$\DXq>@QZ/1AC:73)shS_[o;&%iW<;^2M3=hU'@TOmK>A#)OW`#A:N^@bWOpi@[3st>adqdQF>5]CsdIlI;JrleEc;"dtUI.iPA6A:eTAs$G^oKcUJ?+ct4idA+(`C$H%M?G42c*h(3Fa\7j^#U9(`34N8R1b2qJ_dr6dhKdU62W2L%];]8MN@ipji.6s*fh[Ji@bJ3Agpt_cIBU89Tt('!t)B'J`3/,W?NaYSr92X9t.n=3A.djBQ3Sa0p:@8/oqFPYh(*P42s" 8@:1D\>nE*sn`/"^ATJS3W/?atV?Bo&P8@m1 HK;AS7+K,*FEm#<ciR%3'[*GYK o@\DojfNB4?*!/2P[!.<rahUR!U5MDX_ka'l_h$ cKWN"XN?c:Dr`)9'hE[2c6mD[*_OSGnj$65o$>4X9_oqJjXkHg=S^#8RWRp1`!j)k*PY. MmlA&1\r@*t$//AKr8F!R^.bqmse14(AF&Z:Q=o*LSj:>FpFn(erd;IsnaOKAmTMH)9G8G@YFp*(#nh95M.@?iX9,lK"]%r<HnW#qJN=[^I*9=b CC</N@eVcp_AB^+N'ATI[FW:73C<4\*>><p<^' T01#ekmY?7leqSFN_a? jA4B'I.VB_K:)P4#;<V]BT`6=ho)Xd]k<g"A?a!!&o3C3e=T1D-E9EeVTo9o7BPRB7?^_A9L!^Cj&h6f4gDqOE_g'$opkBmGp/Bs8g+]`(LG\#A<F1]=%\@e5"9]D4c3="g4e:eSi+8@O$g>b4#CR*A`cT9q%CUV[_(NYU7LJ%ciL(4P=DW\G]/7)=M31E=Q=._hI1+(Y#4e;EAK9!6qbZX7 9P9YY8q7a\#PeKlAWO5Z5A(1/@r<VL=>1?J@FA:X5[0+j9I9,#)>26ScaPBl_T8G$RAk4^b*K[F\k653<aALe7A<nT8T0 ^mZB9WlJaI))n!l??]`9SjfY/\Pti$+B50"hp#ZWBm5NW-j$bj2)02!^%7ZoFAZ.JZO$/%-2Yg>JaN1Snf^lBG1o=[$7<``l1jAI2TsIl-;#.16D%>E(C^t65)0Xm0(CkpN9F'Sg]VPQ`j/D3?$G+?L;)$[Sg$(^80m<].TF&C+h8%[-,ojf;GN8 qWYRg/CPL$qj7b?7h-D24*G1mC?c;"Bq trOD*aHJ+8:4M1'8AA,r2*fK!%&P)[.nQ'af=`W6<gE9T\?)l`+--aAJnQ_OSo1=dmnEZmdR)SD(+IshZn+`5e2"Ba7,Vgb/'#?qNL06;<&#BdQ]hS)MnrJ;XT::XPK!5"T&sc_@0X .h[1=.(;cf5*doeLi"=?Pk=Zmjq G"YZP&o4^MB("HBgZ?[k2l?WNBD5 :,,[[+o1#Y3koq(p9t0MIjV/dlL_-jJP6n;[/e*XWW$'SH@fo@j`(c^8R61arG&O%a<ZW'7]"hY":csZtB-IW2l[W)N53\_\ M DeXeR"9P`<>/0:h9!9W06U2&YW*=m/K2@ANJl&KPS"e:=S$)sYC< _8E*4`=d\]NMLW!R*=5H!@g4rV7F)AtX0!^U CFP4e-:b?0AOmp2+UQh[PYK2H;@\cmW*!QfTraE2BFWQ]\M1jBphT6>_?#8A]'A./9<kY=+Ip-?5l-&Y1Q./Ub@Bs+Ae.3s7:YTdSrKF]^li@*( ZN"%,FL93BPrOG.A&7I_Hk0*C2U *#WP3V"=ris;oN,*`o[iJ:"RrHIOQ:e$FQpcMqLF'Yc@ERqN&PB;No"YjE+JlADehI^-"5s+T\XNho-S<,0+7SF)g$!FkC@r3$M3 _sB_+'^'!JcQ6-qL"U<3=1o2hL,% :jV,:EJ_1Dft$6'^7m[A:alJ.bFa)MmNkZ^T-SH.4)Rk[cHY(7T2@I8Y[4XDd [!ioGAh$<7?)%i::pZP/p<VE"ZpD.@M)DD,R"Z^raq- p5%UNiX$_D..(1,6e1oeAFI7#n-C*eSlgjrS)C40pMteohS`(l(?$<TdWpd($/Dqa*K!Z?s*;$8_.XkJe&n;8L>'.[%o8W_KcWtoF:*>W,6PKR`P=$N#*b*R.0.F*gIQhgV`)j3mcLZDpnLK_*&=@)>B'.9sP4DQV%dnb]>=.f+bMq)#kHHUJ^dC7"RiAL@QDLj#r%A#QV)`5.<WMs7@PU5,<9Fspt[AO#1g kTcl+#^,ON`6;f;);<?a?g;rG.N_#eABHX1.G,"\Y`V1Z44DDWo^4gKGiWTAB;g]';)^E2t_rp29&-64<()@No1`q-#!VDe>6esha9J7*>-[C#:&N(>\tCV*aB[]$XQ3S@tE<$%^Njd>#n9>.K.0A\j@pEbP:FBAt9qap*"GM<X\_gV9.ElN>$]=Q7 7?kR7l6,)fXV;^^GfoFNL GVS.ni#P\@Me] <&>H5o4(B!g9<F\+7_YY"fW7'$\ebd_U.s-NeAi><a'LmjQiUj!@PB<Kp#bh1jPfhb;dKE@6m6b,T,9im,:$KL50lp=.g<>pUY5o%[o7dnYtg[PlctW`5`T.RprS0CD2m?*/a.?+sHk0BpAtr84RE``9iK"^$i=aMg_e79AMf_p1qGGjY,=@>E+E%5Ft PLFgKN$;bA)XYFNdg[1DPlck<NMsAb2! @0t=<B>ss5mfe"A>Sp@R`mL%KDnZ/=HU@ZA&a,N"cA?KOY*(W &UZ+f]Wd6R`;<p34mA>q)bgnJ(m>9D/c"!6(ki;AlB8UGY-?0m6l`l[q@J;.`RF!^^psAIHXr)CMPbDRNJ\dFA`oVG1l&\-?I5QpAQTF+RhF'!#=F\bOh.MsUKUKr;2:Arg'(Sn<Oc%2V=E0&LsO5$qc8dK"#`6a_>l$W078sP:kPhTiUGL[0Q<!sk8-8t(D&Bhs!nqg YL(hX!`Y03k:*R0'(f)A.,toa>!I$/!+)1i!@5+/hs9@El2XkddQ&JoX4f]cB>Q9#EfY':^D.I&Mtl.cAR@75]Q\]PbSlsX"G/Z6$NUe.$Q)+gGpF:I2iJ@O1HHEgA,d=ZZ:-jLe0U4QjDtN:pK.CV:d&_^:U(,EGZPF5rA73&L8V\ t E! Vr6\J;*\[NNE8QqA\(m1dQ[6VHT.\?PWq.O:l>"WAm+H^AdIs a_H\2FS*tLBZj=*oi7+Jf!T##@ <Kq5IqVPK9=WTOfIXX\Mm LmXd/f[`A&Y8gK)[;\$=eoWIBh<Z5e`Uq&^K2(%p.T JD`TIj:`nf*BsJIm\Zo`Y#c$3YE-PAQ24K&DE9t3a2rA1-JNo)6pL".L4apa<,Y@cO?f4d@d;Hilg[9-"kV4DKc45Z2'_?OnC5ZD$<`:A2+$%<KqP0W=)!6m(#1Bf\*r h'ZC:&"NGQ(`84k9(<U:3H[6t%@?OfjrtaR\+fJXFsGU&[tB23C5 \9h 4eF6b_p`8VsUQf1J.4M@DoQ\=hpcH>'gR\Rgh(GL0^)a\?aZ*53&&t!Z9_h)CCT"]^?XB+>/ZD>e,==9_YQOYZ@=4C%J)n5"t<7mA+<e55U)s9!.>s;l\?K%e@pCjq)Y5(QCt>[&L4m3kb&5/7'Kmq^pWUME.pNKcB Rn#b5Ti='Fr;c64M!@Hb:Y/O(=0T]K?8JnVf %(:H<59Vl&6o#ijl&r9SQl(#?Srmt'#?co"JSWBT"7)PanS%Z_=4aSf.:1-Oq>266R>OclW]*4h9_A,j/^V PDEN2e7cnnNn6Wb6qb4E-RXK/DC_nkW5roNrb0k/T_mjK:8)P@[ i^-:L]_?JE.S^im:89(g2?a8F\->fZ\\YqY$79i>p8l."H/EmBP=QL9JX[jB1N@,c,bg0f#=/nPLaQA0'a,oX)<B"@$GCO3CWHdAhP4PKJ$sH+Z3(`7t4b))T$WMgJGSp%. +?Y0[icHQ=e\GKmE5"pQ$>C0Q1TQLSYs/$;aGm 7mC&<o!2/ph`YH;ek;#pT7J+RO19@k7D0Xk4K4.sVX_aA3FZfX3(9Pko:q%PY.H:8@^G&pL__G<O+_o(Ua(n>5^![#d?bcRl-kQq+3WtiAr"EMiTTUB@Te@YkR`1W(TfAf8a?dP+aBj:A7C-eKSFcY?KOrl$U==9e:i"gA(?XBcK`Mo,)igG6btA:%C$6shNsn7=[`83AOth^RM*W%*oZ(I)WKae@:K-"Jno\#OaH!"gYq*Z^d@97OX4'%AN+lQWgEd*K,\=L,iV]!AY'o!ba+PXQiaViLAW P@Q$n!V9n;].sM$^o<.[mlHAcK?b*=XcROiN<Ch#k?6CicD4M+5'HA"JL'j1\s(gdS<*[^`:i?`4lPF?CqVqf,qm1MJj;o.V,X]50r(t-JTQ=Vht7!I_To!Y4#4Po'K'g#\;*%qRM& SAS/0"^]A]ZQ:X-VZk][D(N`A^7caVN+:X?%l?t,g>F]eVD9Yb*&iq&TWnlFgb e%1e1+-@ gN*Sb/1q;IZ%mDJM0r>Yo]i\ZA!%:8UF>@CDT-e&t[',Ag5#0GJhM''L'f7tli1A(rPBYUhe5U@\%!;3OdHa%qO4V>!B059/Z.c4-8GCm+=q0A]b;41rQ9W229`FprnZN1o!#.$^#eAp5R(*1K;/\i(I0<_ISZ>.?\^Wekbs]eZERn@5"3)OD=QBrN[krVmA]00HjR(j=.=3.#G&jDT%*%[0QUAh7RGV1=O>a"T/KV)b&B<%JOM?!dkEf-q^/d0Mq-Jnar7HsTWVeZ3j)ONakRK_FJN)[YTUQdsC/$^Elt/blPLHhiW81hWX?19KVeeB()c(piE0CY*HaZ ,dpSJoWHnrkW)BtO<pa?s;M9K`E+1]$-W.s7pCC(&AL Kp$dpX`/Y0@RZ5B[;1Cm"U%*D?.!__E<[s=$XbZhT2iVH@[a4JRDt@*XAh]eX<V,\NJ"hO1F@-! (BO:A<k7[F^_]2#B8J8%.r+Aa$^4AQ$#@O+Ig9gbX2Fc]=QT5)'8]5B2oR_:9]P*l+D?[V^!5h&3p3\]:5Ap#7LKtn<j0pmknLqK^H("h'\o( IIgNO'Y!i \nF@l<.\R2_Jia9p)89PC;McU4bKXm GCE3.BYl`Wt>Arr4pj?YM2555jKLI`2:&A^ad)s,#0K4mXTpU..-@*FDU@TX.N7>%(h:JBFtYkr!KEG>Gh5KstO#)H7Da@7j!erQ`_6qs3 $8T6D1gP!5H5\`nP-_TCk8CKoDJLNX5-jbnhU`g5:gTf>g#"\QUk=VoSJ4d@NMV)ZYmbP &"rDGK Q7roi.+^XkhrP\VX!m(:-,lEY*bd3B#1$*UY&ans$GBc*:E3=&mZM419#E/mettA@+'=grDQJLY^]GP42R;c?JZ5;;LCnD0a)nRYoftWdk4_c(5#A?M;*D.!O[lT\Mn(2A.$F-H&+P/rg&TXCZILAc9YjBXA'28IZ'!!F6A__mBA?D2CX1:H?hQ^54O\Ba;=F=?rYPk3)4.^c^=OV]b3??]lU%$!*g`YkAa!GRG+UQtS8=)A!Y2='d:;#Fp8B-X3sl'qg+iW.EDU5n3[1"]1\<^4W"oJiE@Ma*CdFJL9`K%-4 'lV:5'G`mj)[]bgA3W)e"3ls`aP%05SDcXSM]d$;-mOc/?H)NV/#j-bl0YG2K?_c(N\5AtW^7mP?b)3;!!$P8\2BRsML.(/,.9t+?d>2(BZCk4AnR?AG*Qfd=c9GAEfXIp9(a3T8Wbg&+A_MN]'p$EeTXB0_4LUB5YiXOsMigM*SY2?Z9+&=gHlk\i7*-M'TP!e,!n<o>b]0i21r6EY@/c,*np&P`( Y4<s^=Dgng' J"02:X%.ATst43Z;mN#hL6@**0Ytt>ntisD 'R4DV.h7e'=gchIDed:U<?P_d]h^J!(9JE\/NNZAoKFA1'''pWd]Z!HFt=+H\?U3-I1!#\;rHr+>?bR9=NO,s\3mm<lSm*]cA_`Tj"3964YZHtA :fYs:Df7f6OA>[#O+:8+6?<J6MVY3eog0oTM8!Aroi&1I//0]^EQk-kpob;S%kt11h,"s04 4fna\a]N)^5+Jt$0j*>hRRS@*VAL,UH\Y`"Da<J4R6""j5HnNI$0-iTl-3+Abj?DG6QMqq7iig)U^+$MN6$+dsm+^V4q9A3Z8!3i'ej%i0AS78EG2%rH=T5Y*aj@B=DnAgmMcU]W7b9-JY!+lVXTmPo(FhdrnS>ZcgTFqX<"UYE7F^DrG?A 2l3dZ<46f9*"WB"Cd]$&VAo!JK0=YnoF0QN*ATZ\$16RY(qg]2F5&\,(29'(H'8q!)V_'pI1l(R'm444.QZC,@;7AJmP.< QnYbCkEC]$2,%OIM)'snFB^4T%&X8RMOS+8Z\?J/'8/N\2Gb/<20A1\V0IN$(O.MDh]MhK+,NAN'$KKfUXb(L/A3EWKOk$Af7;ms"Jrs%)H#VL>#^90!4<KS35;e:oI%GRaF6""Q:l(Ch;!7I&-[_m[\Qp/U3_)a8s//PYdoX[##6TTXFL%HIY(T(;d\N#d8I55X"6k55Bmf1RcRB!(BB>2jF?(+btekZPD-_>RH/q[hY%eNS;MAMkAM3[E<2M*6C)HQ>3+I(I^hkgE*;Ai-e7-U53bDR.E?0#f2f4(gm"m%B[2J!3MPZ\DXn33RoBN=>op\XBU(.:g^)g@'<>Qc#9e?Z[55L]jnW_^Z5U/:+@/`c9s\K`)6OZ[go(agP,i+Vpbid'A:N5]Q8q%V@!+/*V%Utd_R?MU1e+;@:*GA/\DQjcO8H])p:4A^,i[:\<-1tj0VXI$->% /5m(OC&";77"BmI[^.8C%_;)AS6+m,;j^hKG0`Nenf!@%oT [Gnf.n'Q1WQ,SMVp\'rI-M!tHce><V6:k5-N`h2qAGfK%a,G#l^D/l q&@h0edE6.P C 0`3btXKsBKFg4:C!!lUiL"5D[+NStAEB;A@EW-_sjc4hb5GBCEQ3T7U!OE7dN31C]B_ &Jh@gN+^6hk\GDaJO0A>(+B67J`NiFJi7SP1>j>$)&T#)tF_b;p[ecN,Y?RN!$F!/_>;(>:;GVT\dJU#nO-qXhI],t$V1aD[/]-[2B1%l0i\E$fDCmGK?hnG^p?K_H)\#UCZ)O$C_&JDX$F/_o6UJ%'qg%#r,`1jE)lDL^B;TnsO A'mk5pi/1Mjmc!AET;Cot?F3[1J"-(i*X%eRGp$.nKfVJ=A?h)4B1W&b6=8P."oo,?VWWIo-<TdmdG2FEB>Y,DZ&DL7]laAWLW)$sI5\NQ5<.eJZ?5(h.L97rDJa4bb&AsH</gZ[5rZ\mWKlQ%R#6rcAbsfH1"Zf322_3l4(cT?q;dB;DrfsK\mtfJ12.^c!hlcFJZY7qY\S$OtHXpPIk<mY93^ %Q6*pEZKD@n*Z;:G<:sQN6,6[-tAegs4'`S>^!Q%=5iSD?h@%)<Te#Ad-R%\^Ahe\oF@*'f0 n-\5R:,lm/n5_]iji%d$;!]W06#\Bo@D:o LPPEM@d&JW\n**q&Y:R&E3b0>Aep ]PP*9f"q8-]Y$hA+/bfbe5b-p!"H(6C^P&k&sipE\-"cb],a[B.kh^ ,"A=/]B[)6L7'9B#LjOR ST/]7ID`Y6/n]D^j+[A@V.&UXVnS7.J0Pt)<-[tZqCi#sC2PJ*68,ngP?: D3P<!*)9ta/$=.'q^dIRP.*ec*2/^Y<k /V5DVNTMm%a!WONr<\_2/bWr:V2+islr/&*'Zk HO/d(QsdPjF0l! !-Z ; lG%9Kd[^5*5$'hPI4W`X0tse*k;Sq75g.s]:e"5Z2#-%]rg;!kQKk"gQBnL*6:\eQ]YOr/Oi_Fmd`)OB(1r<J,P=3eH'4n=$h%(-Y*;A<M&3?n?b&&J>dC&JB3Db^e>=g[lEAA"1G5p1`7nr@sDgt8AP7:\dFYSgB\e##sM)kQW=tmI?A)qqFKfGn\F>5cIs 3qM0\fC]KJL?A$.((ij8>";_a2[=Npr[H",#s(=I!a&*)TY]bt8L&bhPq2TK7kGdQQml<[*i]jF9o<lpXm7"R.m=nd@^d_*;*32P `cR:l#kfVi_Ct1!r_cb15R>7$]gK=dd ;>jU%4:(^nqQc/c[>T]iS9sXK_UH+UqrL!lQdM&_S7gr/tbFA^P2"#f[kYh.^Z(U(al5m@TL#Et$`(LO57%Q c^t1&\4dR1F lqANA+o)'@/IetJrJb%b/WR-$8N$A=d38K3[is;Y.#7=Xt)cQA:lX&.&;cdq!si125Nr#GW'f!"@jX#oNts9+25Fa5[jt0VNpBVE2<Z62'.@de_`T,K\!$P*R8R3r&cm+*q(dVrL0/]j1p/r0)LdqN;A3'tX,EmZ*E4IZl8ci6\^Wf:=J5= rn^2Am]c*r%3E//1#Z2VCD`\97!?:@qoN.#.%.@c'D7la&ZK&nAeC+.Zg>7/@4IPk->VGdg$ZOI`c? TP)OFJ8`%nhE@=SflQsXQr!T(@5hPA<A<G@B?B7)S>F;mVb@m6<2LKDedE(o@r&F>#F?,,\Xb0c"]!A31L(/7fUf4N!Z,&O7n4YhpK['K>FVE1R+oT'4)YR^,=FMNCUIa_hS=8''%VofLdgT,Ik*DggSD7*X0:C!'`PY]qfrU+76Xl"P?sZKmLAgn*LrcV^#mF=1'LN<6+[.@qTT0;0#N"FIV,F<_s=^`nF$tm"1h.-Q4Ri0*OI2,iJg05>*X"!i#_ctf)lV"?kn=1*0(p_]SU[%U4J2q,LAA,b-h q;BFRs6)kBgp'L/4EAU/kf2+KP_o";?t =44MWelLiom7@UfkO:N"k\Z2,=AhrY$s]'7&A&A;_I8Xc)dMP`-*Db9&U8>YeL<4#-d\eFCM3;YM1;A)8\LL9q1G[fCd*(M<R&ZTNICKqSkEfD_A \43Mn7e$1$oC&))W?)Y'W-0ebjkDZX;\5r+^b628MBJ1a+@brWkWEAagc8QihI#OP*Ai$KHhkpBW7.-(l:@H9,K$h=/E:2CsHP$8he3N7pql-?cPsHfmAXSROL`-GN'Ihe/I&ia'RhVNARA9a V`Lb!bXJWCn XQFG?]AN-?Q4!?sZZ``I%T<P l`&k#+^@3P"[ j/<#11rEF")YP<E-rPNIZ-Z;8 L!)X0kDa?-faOs0P"5D-\Y?1c6(;nUfh?CC)K 72J6E#Y^qmc)-)mmsA/28[9&4%-Jo>USZk"/LTs42#&YaFl1BFQ*-/)a>>@2X-(;ndjcTGT d`o(p8ESY&Edi;q9?#:qG'"AbAW2$aK/;.UjRU0-@Ih:[$n!c2I?n'^IFArki5)Dc2,'XQTO+5r5L(^N^PP $OQ',ET!pp5dLO-E1kJO9a2=g02OV?Z9DV@a+fASkLjo)aF"JNjgGZ3p^8g5^N:58?,)JK#Zn&4-eGrHXU2Z9OPj]p5$+/Z$-Q3=[Hib%jL6\6L3^G(sAZ;/;$!9MIe!sVY*c-)c9hX ^B8!`V0=CY5XW>FmA>3X+M2KiWJl#nRL/]<<=WG3Y=t;_j2hS?_12 X7O6lAq.%n)&@bbm-%g,e->2ipK49HW VD%@c6'SE/81mAL6?\Z0ig9"l(%-&bA@NPapRAeBosJ*H;e<K7<'sYW't &kP8%Be'C#,qA%jdM8%eZJ^U\0eTAbi)t?kZBO6`+rr8Hmorl.:&Y&XLTK%cA *6(cX*IPD-`fNEef;HtGD'N#7FM78r%)KdI8!e*ls7%6'(Nm+\/^%08*KBj4t(OU)6bdlc`XK1h3UH`(%o;10I7]=K-T-YY=JDoD<%HFfInO1Pg+NqW0Li]o>SBq5eNfa7KI\_`FAe?f<*aRKKmm4Y8\mY.E?a\AnRK-'nCM6R4_rZ&7@U".:pJcl[+SNVAp0QVkA.c_<3!+/-KpW#1#gPoTm$-AVaQbMm)+` #cY^(s1(\d3-pG[bQTS#X2e>jSN*6$6& :ZR87O>&7=1C,7q9_`l-f]fln ^b`^CQ^QI5%nAH8=j'Z5MW&BMi(Osr$*22[[js_:%J9Y7FH9^/$>%%L(e:gQR:f0;s24gOi&J%5[[39bQ&f/%CO",Y'QZ>>&g7=ag=@q&9Q*Dfp:7-"6hJ<"7dXNpIT1d;]"s8SV6l?9Ra7b=heU^<4Ackg^FQAVhiU;YdUIB&V_m2#B$/c.`Cf*AK[!*0Q@fBJ#X)cZpt$=pY:_&bJN<mo[hZpDtn>Xf@&01[g+j_Y<FH@@m/[oiHc:5gpsl;3b3T)Q(R^"tJ3>1bBqBk6tDRZX/\\lmQ&n0E:"@BrsAD#`8MX5d-;EU:ODs.Mkbf m:\"08hIRg^6C=kItD;WM$8[PMNbMJ)K'3#sbH6s>QSlh5o1Z367dNDXCRM4I)N>)SFn!:'E^GN0A@6-6,sETk?Ak8=rA$L_@39h]X%-5JAf,3eeCXHWgo^3VQCD mVqd!Hl\O$15c8dQfHVSnDCSr'0nDAS:Y/Em?DMWqc.hQ2Y*;WAK&CH7F'gWTSho?DTQOj2_!#LEBP=NA,><AaK_&KX;or*Qqc_A9t#E`p]$V^8\d'bOOG,p-S^9 Gn/iP<PLop_"\s&#fVQKZB(Y&X07"o'p7]sD)e/^gQ0JoIh^9)$%Ae04QMp*5#A+kg!e,l1`-2^NS[oJ8Q`(3,j1]81/!Q>KX5&>o;_PTQRO>\Y@0gCnerAWa!6D^+KF+YL.Z'b\-"6(F?g\OE;Fs0kDr"1qVA_PHSWXO&;Y+:2mhcGaHsS/G_Z:!'Ch<e_sN:0E($>Z7I^Z<+:?0.^-@IS@1@? ]: !"$s7!SE?(KJa*CJMmdD,1rRKD5O.6t:j6IddI-! UfW#H33O'YM]hLQY#JT;=5WH@V!nO@BSd-nSJ:8&k"0'S$Qt[-K3,m! RX'daCqMS-dfPHCBe\fEKRoF%ICJQ`NcG'M/SIfQns,7=>U[_4iF(LO(UgQt4h844%[s<n!gW<K?NPNA2DJT-6l@m_RX[HPt9.Nn,[rF/56mq"Xc`\&FQW:f[3_hC1!GGdd3'BZPt(st*/q"Uc9.ID(f9reXQlk XAA6#*)XTjWo>2_aP!mj4\1G"6fA:3./>Y!:&bP/+NL8:4c6+_-F +J_-[E[sV_J^Na&RTj._ 6at+M)2&DF98d.e;]b@4%KA9;F";Ag-"t8>l(-(54VB$\=lFO4[5tqc-,QtinJ*5]D#i14`&C@oSP9n,ma]*SXn3`;)fF6GA(Q_fl"K#gd$T&_Akelq#%h7kO2qN*YPY*o_8'2gXSmE,Y7K?"$7(KF[.C5imgT%87;WI^Tnct1@N\C!+qIT&a!0U"[)).N>,K-rhQ%p`W'RM<.JY@RHepUbb;?-3(a'r\;"hk^d[7H<I&3VH2EcAm T@^N>b-95b(/M/f4"so2f--WAPQ7-C<+!?B0SrE$eb.)m/-`A8+-j44d6]U"\QQdq`^if0mrDqa`P b0B/8cni((k(oTd>Z[]d8k\Glfo25A)^[)Z1pE&^5dN4HG^($FB4BFg%TK1^Y(:,M+>4os9N=d[AJ)qZ!o[J9$F:6/G2f[o[3D?+N@O4:U29OLK,acrJ:B..A%N[o=n3%!U5jleoIPD8Dc)SoT! r^B'a4=+%lp2%(*r"]ATCh^+\[KM@7 h7*9-S(fc_eaUK\AA`U+9P;DQ1HPb@Wc$NX%gOgQ:g2dR>0,e$g;\Y%D.BT_jso>FpDAFI$9I?FUMS1?$iI5enW`ICBJSP^Jmm)pjnB3.%s?-M<KLW+P0/njN1btYdLrSZc-Rt)^\oU<_=)`LsprFmOPC;^8@1[F61!^is3asPVVA'Eni)OdJK'7dqL^`:;t7^cP9#ph\R0Tl+J)=AMPBlFH)J,:&DR)OqXUt^+LZJA@(=0>H[t$612MJ_B'"R X\$aV".J!sEp`q<'>[nbZAbbm$Fl49A?LS%Fd%g;[ggO;FQ-i0B+(CS/-?g*Jm%1PH)gOR?4Q\IogY-JXn8S^Qf0AW<QC#]!sL1W[%rV.-,7s3BS#@4EF%<Z7\ao\Fa7Ib!//Pt'RPAM"^qK*8)RZm/NMaXWg=Z[(2Aaj^OM$MN!&$RIQnZ+g0s>Zt=HjmS[)Y'CjWrSUA%1&4>o`GA$gUU\LS[kB+,r`/cA-J.KWbjd4]X-*$g P\Al'q-d3q-AfbA@+_7k>AtIJlL$$M4qo21\SQFLo1_V[B;tT>!$^feIPTK)/)V>EYiEJOi`_) ?<BJdB<E`<nr=RhcJcqX`gJ#Yin,d?K.2 A@oo&Y[CAmr1j/1ij(2Ohl[p=GM:_1&:_9'RKMYPB60>c7Bk1)XJX#PtR#eAP&T-j2i6.=4tsZm\Ht9XAI+;M@Zj>lh6aA*P^9Ymg(-nB==-!A!JrP@Ujn,c[r*(jRfkdp?C`Ka'\tCX"c-]eWnE2]?!>E.353qKs7+!n 6#@GFonM(-?c#7/U `%=RF:Mq*<"(TX%6m'N##4BN`FCU]KA'IAZIS6Yl^M@.Ac9lM&j+B^nBPM_F8&U9A>4A1\,?]Dm"HjZQoeBS+g@P*r(0$h-(o%_)tF-^\Zaq[G!a!2*+kZEg1FIUQoQ'Is@!O-q6,RDW&L*cfTJMr;Oj@K-m4'q.h.&*g>6UZ=(NAE6(&A`Zt6_.a"'B,/4g6Hfhln\_$VK<9b%sD6DS1ik7n?VoNl2"AkNMRJ(srj,ggIqTJD7qinH'Dr"1T?,?%h<c-Uco<]qYh5_7APE6.!sA'D[Pcr+k]LepHG2bmBAdernTRGZiUJ^r([=(oV&OWNEHV^Z6icZ=$@b]<$9$iK<H 6U4<]f8HQ[9X-Q=o]LQtcYqe"h)`m&Oa*Ei1\nUCq-C:GABZiJMU.]5lP@ *5='qA>bS$j=<-khf7pSLbmIOs<af&TciBf.>&lf^:q)eJq-t<<Bp4MYX]R,p3l,/!L6f(Zp9$q/+Fn,<<qtY&;pLEPUnfo@kV6]lfE&lPW6+InXRm2bGg%Mo_Fb_#j.?mWW252os0'QAH9lBi'8c%lQ8\2sXi6gAH['BAoM6Jl+>clAMI"nj1["LM3$H.A[]_V;R5U&`:]b&6Y#jVf)[s2<3^EFT@'1k[m.sAA^O_^LFL5<i@I!Q<: 0afF/=fZ]gXKh1M'(5%DR%iJCa3faIJIN*dHkYY= Fpl1?Kh"<a558gPl90dr3q#brqD^Sl3bD>9`KL#`c@_.37hW^3D!7q-d+sH]H"PKBbEGaao'4X0VO*q_]DiJ#ETa`/.\VTG:6;/hY=Wa!&dS'jIhi#gQg53R29DWgDB2mM!@0YmiXSUjT D!&gnKpPXUESfKN#bk#]%`T&M!DV5H#\6\@D`s#Yflk3&2%qXLo/kH-T2+lB3B0d&IsS7IA^oG>>h%GSF V<Tl(c.j'6N,P*4^!dV)M/,GgO3Q(EU)KKAZ4YWF`Af<%3l#tcFXr*o*R0:;H.G*@s&D.3#ZRe1J7mFD[L1_J>]s/^>I\V7Whb<_U5;P;9SW;iK^'9MkJbf-b>'I^DY% 6/p1lqe$rmpi%@9QBQLOCh9Wa$ABDN&:17**U,7=]j`42D]FA(X='_`0=&J..5R6qj#'X=_SNl&n<0UYriB=h[1YL>bUtqiOrXhb)B t= cb@@148"gmJ<%kTK QA(<IM,'N[MkN&\``#J\(MJFkY+*hpVtsl_anG>T9]RnQM5*,[3K/00#\qa(\$r7<?GgZKV#$%Seam]F7HIVt6if-<f2DC8"5qiSVoLA]qZ<k@k37aQTED(EF?$5MFrVcnd7e bGbm%e*-./i!K78<[pe-RT=Z1/sDr^nNJlS5QWlI"B&dX'Fof;5?R2\pttL\cO> pID+>)5j.<J@DiQogea:[YWKp8$ehT/"\7/&GZ%&4TXHHXB'-bAHZ14tYFA@+gSEA$6;/Y/fS\6k87OCI"kiM*Pt2!1*B9SHM=KHiqXb4NpS:b USaOSpsJr8Ie,q&/00NR;XCOL**O]1D>mCf[oOPbk *Hq]Un-2Neb**1fRf$19k]UK#)%#/icFAV62!V2K=>\f3(@^SAhR6rO9i`c?MtkINO)W)6m9r(H2'PB gFG4,I[Yp0;d1!BqB[S;'L+& pVd.dlcQ<O]f*sH6qpk$5K;1cA&t7+67]MoX4rOq2tA=J7\lCKa]nH*hPS@a8H+SgosRb4t?=m 9A_bMP9.Z)>*bXk:70KQ;WC< <O4 0[T,\M0h3dL;rW*\m-A%C,B=p:F/QK'WOG47'$)1C*`/I.tc7*``C7q#;%Tf+P&?gn jN,t22cViK-s22LlGpZsFE.Sa;f\QVM!`piM`[X/BOn;b]@p1I3\*D<B#Fof/F:/4Jp5X`4!Ab`/ ra4j:RFrQjYq`!8AA!a;<G*is+]e:%)$;VJ<D')71 oSa<^&Xq[p"LB5[#]ESNE-El g9qtTB<n,\pCoOFWD3=>EFEEB.<f[50b;?X"Octl/m.=`A`Ac0o640&tI2VDri;p0^6los-<A4d`U(P1?*026IfW;UQ$^'as e+AXDDn@Y+rYC5$pA3 !"UmTc/WC 445`Ifc CfO$0)Z8W'*+2qlG#6SXd+NIbZ`Yjn8dBjYX!6NT8<27Th\HSHD2A5A/.,RMNe^8 Vs@?3<bA;:m,HEq\284<J,m\tdg"(C=LB')WU_b!@Y0R_>A^piDC\,Im^#IfeW(68F8jA%+/Q>s/BgLP1DB$OV`lJ`REf[-Z?cGs;A?ec2WMM)E5QT;A10:]\WaUT)s%-iC%7nSb6>=Qf#!q7Fjj+#Gs X$k(m9qAm;M_4/:AsX$Q_V!L5@1`aisf--I,&;AC[7`2P4,RNPD45@N?C`k!ZR_YRgfWtIfA*6Vok#S+>E@>19/TQVImrkno550EkE"V)c9'Ak:=[$#_,JiSFUg'rJZMD3D'fQUc<fT&:"hgO5pc^ZHWXNqQB(\EDO+m[!YAUldAB_H<nF&==9^g6=k#&Em3+,W.[o!T/<YIC4,LA;3AY$S1T4('W#o'bOi#aE]V9ZH$,T-qp`AFST\\8a?tk$20J<4N:SA*9HneA5r%VY" $E7K$qt-ng>ZsQ+*q/MbR]JtbAA;O?Qf.X,4.#q(WnbNEd7K_@]eeqZ MCJIP0Qjl<5XA#+c(53G+)42KD1'>-#71FPlOpT:)L=gpA>nio"mCS/C>c^t@An]C_<n#p>m?Kg$/\&fJ3U>TtJCaDf&!+O"S(\&i!0'Og;Tm1Z7t@"jbk[D[oI1qsV4"i@3Rcq&doS$0o-1+U*T:MB!>$E8qA:,s4*UFg]8P*P17W2"*NZWk6$'s2@ `bOp,s1C5>h0fC!gX`X@Q>># BH'>bB$BF%'kd/j/8KKIm7W_`R4Xa49b7+Fqb4O.qc)A`iVW&6%S!,6IE K4o@(lpLEUX96o=SU#cE:J1HKn5VFb3T-kJh!!eI.b-Mfke/EhEm7T0U7h+q7K`Q*]D0X6o$H Y8:Zi`Wsi*VFDtgRdiPY,A<:_M_`^h,YZNG%YhF:_I7*LF3`R.<-.0(o?; F2,A>sW*Ci][t3-=hpVaAQY?Vc`R@$2cY;'8+[,kc"r;fiQI(6[_GF@TU!Qi4NI*?=0/s$VR<_YZIdI.=9@]gakFqn4@on=`"Z"`/G!59#%^lhAi&:c-"Y1oN:dk;isr'Y7FC0`hEAoh6,2` Q-K*``XNoAc(gpA!A=[nB- r/\R;P`(=7j:UB/(W\F!L8+]h/#]*;tW<dP/ai#piqZ0sXqT_(LOb*8.=QQcln\CWLL&)aA)fGi=Q^DN$B 'Z/_^r$O$kW&dU39I"'[E`)$-X$\9 CI04eEc*'n(Pf>C&*A/Z0Y,Vgksst7)T^Rfi9=38]od>kZ\$]h*9cUU,DMlqhdQJ"?h^/;<Cj&&R0252VkXp(EZ!bWA=nn4a<\POCOC3TO"a-&O"a8Ve(ojXa!k#C6H-"-p#q9Hp-A'421cNd?;Oo\tf(j^fqkBQHM3fdQ']2l,Wa?i;:(<k,TL9^UV-Md3onB` O5?AM8Ed*'+J@T'?`'[>m:@:%ho@6ZU3'gmrAhEq^D2;"=8[O(h>Zm^,jO18*&>tSt4UreJ, +Fk<,;A1Jld[J(W2D"41o[jBL-P_Sg+RI)S6jX1.<>B rd.TsO%nj)X6l<bY>3Qd8@W.`WN6F^j+tJg]pdf4=?q@,eZg0&*-ALgS"qb*St>4bhsJcZWA2!A2X"Qb`'Sr@-MVjYLo."C@K*VC<!",q1ejO)A$'f$)<>FI 7kT1*A_HBA^M1i\j@.^b`NQU\o/c?'Cs6%hCQcD08#J.2$B;aQm <i f@.-%0S=al"^:h*7s="O)\W>nism8,ZKpA<W)YAEV`fS$Zic"4LZ0jAeYti/M1\\F55F"hgO_(1VTt5;\*.kfMF%^:QRBclt%EU$6SWi85Y?5m=;iL4f&("R]XZ[ bD!!n;21s&(='S)8(pOCqpi 'e?4Mb2o2BF8A<F14[a<A'$?m54Q5U'GaG9U; _mXA<,!OXR7SR#2J edc9 8H79p7,A?*qE\f_N*L'0MA-O/C4MEEXbDKZ>gh%.6-UU;le#=CURN+:R,$5oPeg7<.1(okE@\UHV0`\e @4Lto7<1I-jC=PU*/0rX*jjAO>U=7q*/-4\lWG>#KjftF@`/SB_cJ1h9L"as=]ZQ'0N&<Le1fAO[3qfr>0Kf`>Okq:oXe*]j'hn;[[dsd*q`5kH8_TkB_4-ESEqgMU7d02[s#OebDd8tBH+jo*<ZMWi6*K>MQ s)F$.-UKfl"9+f@4'bd<im8Sj-opD3J&o)hH(SQ-*:U?Jp!<^HnJXplhGJ)c%?Q$.ktb[-V4r8]I9b ^6BW0abHAhc-W9,SR17EE>0XsbR^=`NJ*#`.;^E,ftp;/6#AA1(VM\E9m>*4tY pe9V\+Odq+V4VZtYmNShEfd9s<a[$C`3tN%HWU?,p<CPL_@WU#Tnl/nd^ DaR"cW`HAHPW" 0#][5A)`<X-OT]Gp`2AsiC14S3pd(bsPRN&2<bG?/cSCd_o96R9\KG\/3"[,d6_G1Y9aTj",Q0da'mlFm=Q)\h6$aA?Q C<d-^&(>'LTC\)%4Kq"\2p`O,;(n5TVe.JjAtWtt%VBs^<`ZV(m@9W:hSJT#%IA,j5O+pA7Nac7B  ]b+__q9>JnP3Kd4,?'R$;$a!;PEoDHOL\GO3R\Z%*^0-7g_cpbSYgI=U%&?Z2JN*"c8+/g4n,MUeG.ACAd41bI%"%1=A->InkNKHVX'AU%LP^@0n<t`ijbI7&#@H<S.1Zk/*!5"@ rXh:#M<[sYS'NnPWWT<": q?t` GMBK^.+j7mdd9?snet0Lhc-C0lZ>4J=Z+:RtgP<ZPO[_9rJD;o>;#C4#r5!]4<XH`-.K:2=;ZQ1P?+&#Ap2Xii9DO3#$X /pQ^tTS*\a'U"CkRkAfo:NI*"Fa'$a/X!ZR1U]SUBGhN3m=kctBoaT&m6^)dB>kXAh/rtSRk/tah0h#qq6*UTRW)`?9;_&agZ@<J"L(d9&%$&W:rIWCD;q&OH7<8@nC9:@:E[7U/&#.SKi/)1Hp#1CV$[!O:(Gceg60Y!a);BjF:gbLWW3,65%1qEJ Hj;+0)$rN q'#g# UOcf@p,^WAsoi&Y4o(ID6&l5%sAjAq-+,"`JUV/B5HY070!'F3kNWTSb[A9!gNFG9%3-\^*Ieh#e9'_2]DnEg3<:&TeN#WSF'0,llsE+^C,,1'6\LCg/F/68aJrSHjY[BI1'&/`Z08'0YJP9&<=m,jYFBl N'JJ+=t>UYMrtFFj53\c.Ane6QQY,%FtlTt[: _>\P`WVoMnO]E"ne- BL>nM?r_L(.7P,$l <'oV0+_+h.-Yl5hLP_tRUMYJ]#`/5@aW[0;rZ(\DmXN.XR@N&jW8_RL",/`s"4V-[l.VF&DW1%c.<-5p:fY$"bCl3CNM[-9Ji^tngOUdo9WODbYcd)3@r3#hHR'3/K&/DLA\LNkD dM:XDU`=)S3tKgZeTSt^?@Ye&1];%b;NI4qde#_^Q+mSk"caS%p.NAIU/6/Rqq9J/?X_e/^W6"Osj&3QAcf,A)+s$NA7=h2I*O PT7!jOd/(5RU[j/[J+P`2XM2JK+q_f$bGlJVM*B9C@IWNoD-!>Vf$ClFqj;J5\@PX i8T<J>!PLA@M69mfY+<X*5AH"`:nWr/R 4[Ei<d(?-5a:(o#T_E3UAI/P7+LsB;&3Dd \:h?pJ.J.Y2EmW+%D76]`[>$Hj&GV36ko?,P1XL#o#5N]+.>Z&k])W2JOC-,Fe,@o>@H+/];/0<!Y\V3DlZ>kkj+aTqAHmYBfDiW_:I!JApEq<`,oCX2DI3I<V1G?a"\pQ<8[WA>8ls4ZX/CmRi+_LMX4)`/b+Egj3W<&Yb)-,mq:[$).fYR\230Q6N9J7pJs#g"EQ\:O-#lp)@e`NpB[LHo$_JbNJpt&-5..ct@gm_6)]A8qRtA-P1b7-r3X, V<^OHNB!VLciffttgVP`1XLDJ!Us5H?daa?nspLARhrasnA:iF[PYI4g]5E]6X3EUe5-3AQsMm.*[J#*El(M:SIf])\A@hJ6?U &*Q+sJmVC sE[ n5!WVkb!?+n"Ab00Z8gnQ?i=FC2B%gg5qi;k#Cg>8"2o*6YpO_5p7D4g/c6ESf&'Ao/TpH>WhrpA8U5tO-g#>t?SAgG/-h9<lAL54>gYZ9sAX\Gsc0m$lG^/%%H(gY+E#!.iN6BnR`Sh8;7.-ndY8j2jrnC92f6GmAq""UXsE8-(s+n_3rN&04pj]'"8#TV-W/etb3T;$q=%>Wf1S^CEZVr7q6HV21L`<pg-f\0`ifI`/fmVe<R-5.[iN=M7(o[d>6Bl!F!#'UcL 9A`Ltp$=bS7kn3*8cc<+3t6cr@^Rok=*17%(KJ; $0WRPg$7#h'--o22?aWnC29!Y<B2009oY_&"(2@l<D/<BCYQ[tY1Umh++L Q`97*!ZN.V!elE2n0a`[IEQn<[08/05/30CTIVE`&"U#Ih;t:YK Dk\&0BKkQS\=.Yah2nZU$1T/-RKXi`rcB86C5\E*L^Og!s'?s"aGp`#_r&d;>Pe:b$mhLU\XU0&mp4UM=Wqrs^htO1\<ej[8"<t7r\@'XhL5./X,>>aCI6X99s_9C_09XU>4?E<(Di:\Rr&n*^]DWsZAI[iXr1Nr?j;gfRdO654c*'/k-D-K'k^/)NTL5n!63.>(&`hrYB'/-2c4lkKq]G YijUHe@% <O]%H<'Wh\9,t'6BP1%&iciP*Q5^S%]rIiQ(=8^D*t2be2(14bZ G^c+I8%0n^,L+fb9\Y`8.t?GOT9F6BT_Rg68]I<mUkAAH P<F6;hcT-Bj,fi4. jkE#jik[n6@o38=37"3&==8;)">bSaa!<HO#4Ggp5QU_ho6&n1T/Ch8e0E$f*_Gkp0@n;e.;.$Zo_9\mJMK99D8BTjG:>gbLLK,NANVFKeKsmA^pb0qWgWt6K2iFSc&h..4+l)q.%)F$C!Jg6*ofZt$h'"\Y''*`SRa.ct)R$ P2JRs0'eos&9V5Gh"&eaT&?HG.ZUBDEH*gD&TZQKTY07"i]t1'rY8SCMZK5f`A5pF-n`b)U&J=p8?^>+&SG'sn#.X(=Aqm^6S)KD@8mqG/(5]^Z4LG[kML3$>>rUX7]Tr,kA.s`RNDea#oA)8Vc)F;NL:JSMt_`9FMlVLi[MLLAU;Bhg4qXW6SB-6S+]!pkG&/IZE4.J&p\=b/Z6EN9*!Sd Q,S t3mfRlZ:$Cs6d9f j;BU&&\?Uks_bSLr<Qg6XoeaXK?M(U-TeeB@oF<S*<lL$/&1TI>NK_ Y S]tnmL?\SgkPL CKVOdIkl40H<M,sS&B2c#ommg,\J!>VapSC& h8le+Ob"7 J@#(E>.`P`IO(gGW1$&)m,j8)]FGtht?s_B93RKA0!^?f4_G!tET9hS6Q0/33RC$l'-FfdHs)RAH17:IsPSD<PmlNIpQgcWUs0=6?;s+K@NAFd.XBkP2q5XJ%Xcairqr_qfpS.F=#\']lSo1pfm-U\it.)M*HGJ<./SlAiT87eU4R>3Y+L8\e-)W\d`qWrkkoidqt[A6PhNX?Hc,kh!,?,0i#TJAdmoaok['CQ[(*J`8=@FQjRT@N<Q:'-H;2QnVbZC@1"f7'd1[psWO4Amt+]ek!n$jA!cQBA##/-KsD!M@fEI&6?KSpT*pA_.?IJ0MqGQ4*0(_ZG?1Z64:e+F!kV\sZgA+_TAD8EF_T8psFsTYYmKtU)n[4I5Wr)XJXN1[$b]8J9h3[3RLCfLY78a;gq&Vn%: '\*oRpI<f/K*=W8FS\<t@*;^[IeI'U0U&@`qp-h<P4^MBLP.clB'5UpY?@9*Qlqqr!>C31hk""_>[IhkY3E/635,_J"A<c#'#a3f<l0bSK^-m/b1-8PQ2I%aB6hE!"]`sj%K+@^B2+K\O("Z<VV;bblt9p!pQoVgp0 bcc)MeJ9X>`H_8GP=<.%rl'dpY/(`9Cp&Q=>(t<$fm<6:/a!O ^Y,%1&0 ghC&!F0'A5dqn/LW?7ehD5?>^Q=)ZB]0&lUPjW3B^2S1D&%,c%m*f^ @NT>Be<9O0No`VlQOVYlRV+=.sA_&ll/5n,@@m+RDkB(0Oo-E6$VLZX5kAmnr.I<qS<ZmO8=&)*;jO>+?h"Yte6A'Ia"8,(=LJWQ_b-#UC%m1I)6AS6<gO[Aq]oZ)RgP.[63 >$rJ1G$>Y(C;;A77A!C/B2X!Y1$L?Y;go.JT2WpG3O/al,H/Y4TP7\ 5Yf'A&^;(5d"kSGmmD/!7(C<la8B!L#:b!_UHm9,qcc9"DYAQ't=$jhcAQA3"[&tF3\rs;<"hiXI3I(#CMFk0&^73Y9E!aU:m*27;!4AS`,X`K9JgWoa?<V@r>N>1?a9Tq/!BmS%(+n8iJ#P[C.9\h6>1<T(&C!9)jT$8iFGC?fj;An]F\3K'Se$93Q!WqHt"O(D_ST>$O"5mZ?=L>UU7+r7A)g?g;)Dkcf`Acq+bUWt;aeqJe&YNT&U-^MUctE8=P@"M0Fs IZQiji)(!)3I%2:)k&Mef.MfPP2-b!\287:Q O43G%D^9T1e$/B6-_8JZ[ 'JKt&MM9+?&d Bb8IX-'tSaYlD8.=hl*Rck:+T!Y77.9I ib2EtT'^>A1YnIIF(A?QPAL-]4,jJb'g^f@[NRVO\bU)jTfRmX+m0+B+^O)+FDi*4IYq@m:#be*i"F^8N8^f^TJ!?W7$Ho"65r8@s12=X ZgBnWj^XhnL5i],M(#oFKs,YE"=Q<(2.s:0632=M_;Dbeb1Ka3K:I#NQZ)92HD1?O%e]Q"/0iWXY&Q8,7!HJnNs3tY6-($@L%^Hh8EHL(s)tlpa_t;+lW,]"sR;6(AX 08Jb3_VEBs'i%$k."rbc]Y(J"CnC[ES"Z?)`pQH&)P^T#V^J3Uf%:B^:1PbkacUf)p-T8Sc]AF2:j0W:b61-]N1khkK;^T-GD,1Lj`G\S93cH;?;df]meBX"@Q61BW?;N\>HJr@b6Uo`e/FJ+=>Gda\7lQF`2D<Y2glUisK]?(EO*NlsNSt5<N"#Vb''%%nE[@gL* (&/UY_&I=htAcTt28DZ7GL@%BBht?d:37!Y _5dG\_[-qTo6hXBM36q_`:5*DW -cG4j.FA,7`@Gp<Z&/tTo2 ?hNj>@pQ\rUg:_M)WfrR-*a(:?\:BnTFNmO3)_*741ZFb9?L\VNWbUQ\ iNOY<'=m[!K4<:N&933(!kAQO+0ZMh>:<^.!BL-^LXM:sPMhE >K<& P$$UKZ3-Er`ZUO'Oc010APmiXmC$YYLmqD<c:K6Y<WaIHH]c>OB:&JJGr0p_h`U^2!Zi$O$+qqr:X2QU7>g-j$rBtt$:=st_ST#WiWG]Bh(m#U?86]Ll=[#M)r'K>Y(Yd;*Z@OPnc0O6WBIAWqE%ChqLXP"4XRI6g>d%Oh2c3Sl@FcA+]9TN!1)5Z_4qNR!JW\(*OHor2E9Z Y<c]KoWZ@NAB7#(g1!X'?8Rn)J'cn'O&h8n:LA!qNh-URea-o;10&.k+sZ-Vb= B_;AN7@d#iE/O]`6I(Crn(`0U-nYED8MR?4]4CZhO5`>F#ZW3%GOHbk<N=rm<I`\6PN]ZL;4J/e_W<B2=%[OgQ3"fOPg\fPLq4jY. NfR).k@s;6*m0,(D$oW\O1Yd9m;'(.=4'W@-2 >er*[$1[)V/l'oNts%P3Yq0hbc_\G:!%42PVKSTE<e+a#P>Xk)ZL,`sRD1Z>Ht]ioAri/5?oa:%rO%/f\+lI(de*J(!W[Y:,fF+3`T2I12"[ceY`4V&'#Gtn\ H8MPfCF"l*d1/4iHnaFoJHR7tG9rPtsji[AL: pY?'VlW;I"31P ;SQsd6<_88#Vt?#0q-gZ?CY%]D]nan26_$07m[/5'm?0>)^EI@q>a N:g^9DMY!#g%)ZmtXr[T6"[]WH&g#Ds0tq9;WH9RAra!0qPA#0^AM#s_&OM0Arr/Ng0Ym*A"MY`+GmNeHKVI#Bk4& Q:oG-<J@=KXRgr0=A3A^P4BnL>oWQe9t+QN#GW57cYNorf(ETGA<MeVgorXY2`U6!=Qs/iU_fDe:N#IXs,)iA5ZB>(T4P(^CIF;\0s"r.T3QQ$Qn1.mk6a,$m"[6d@91Qrt%s!4.c7(nq[n'"*c0A^I!JoZ^BlUrAA;li[E-fC-F_chc>/IW,/VqFPOM*1+)(f=tmCBeJ`CBc1jAZ<'E"!pa%_Ig`80;/4H ;$'Z%9eJb[?W5NaPtG9T"tfC<=HRJhdRT2GRK5rE#9*>)5kJ8KD,8ap Ap="lA*c##gWa4A-c`if_oLc$L387$c)*TNVJ`'\L?Ok8lsV!A\?;?]46HkkRh,L>aV?"A2I$N60>K.06:4XZDh=6MGRheK(^]]EIID7ocQXN4B5HL4q;QS\>6qp,A3"G"GJCo"Te>5ihQ3`3r<(ctdP&!s)3ET*8&ib:1Ak08U0G`?7rg-AAN7&"lc,r?-6@%T-If4`m`/1Nq>m-Uq\hr\tl=hM:DH@YrM+n`(Qo$h9[[!6AsA7(JCm4J"-D0Lh^=$_OpM##ZRb5-&>iT-,l](anU0gdZA-=&-ag<7)glW=ftg_kRNQ043b%AI=r\!Ab6T&I!QCGQiX+[ADl:?%J,AOm#HF5Y6>/6Ls(U?lmlXW\Di?C6[a-[%$.Gl$&]9#d:#)rk`6Q`HEQ/ZR!dQr_K?;7/]>l*VAf;6-2O"#mFDfes+.%=CPbXX"0s.=C]Zhq%-r$<rMH6F>GDC1]fO('PM*K>qB.H?9h8T0pZ.l<9EPlClV&_C:lPmZ*P+Q0\;c]4WdZ%==5Lm/BXMVTH_-d`::Ol*7q1c]A*NNWKM=-/>O@H$a1c@r.=0@;M*FRARei!@a:#O9GAAO%Kds&>ddJLcVT?IT$-AKATC8^MBRmm(GW\SX/WOIPH?1imPf(^!U&2A=(nXd&^(]XQ"AB. =KtFE$A,-8/Rkj^7>cYE,f?Je-AF"l,CA,jS>l`Z?&00JV$_X6262,/n*m+enS@*k1IUG-1f'C9QR2lG,\NcdHf^*N$JZB_#m"4`<i\0oJC;?;>Sl cpW/6,)5nI;j48=jiE%4X_PFnH:EK"QRW?HZt-L6C#?V6ng iia$VRY>/X,1)C6*aU-mO;Yp"`Kb\oI>?9.<A@?nLG!Y'^<.f.(ZfbV/^jeH8bWaF3;pO@'8[+?8qg6)%]q) ^]>0_E3bM8F)%3T<HS91m(0EYPC<(JE__6O_.;QNY=-+K<>:=T  98'L^C2M,'t],;*2d=(AJ?AA7LL>)+cp^F+5)^?Z \@b.#E=m%WTs!3?5A+Il_aA)*(1H>]nC( [o9'5b5%Bc!k.I-(?Ed/Gn8:sl-(Z\LA irQ+LAqelk@EJ!C`:":bpGCT-%Wism20#Nkm0lX@fM1*XR.Xeh4pHSHn=0HUL Vf1_r._85CGRJZhi=Kf=:<Na:JU N2P_aPt+D*3qZmD2kE^Vq:Q/E^LR?Qm#O!NO^W*lIApPRDTj59oH*lttP3rFKe$Bs3.U:b_#DS+E`Us<BZLX3=4q/cK:aL8 /0T&47eC3ge:Jl6n_N6$<@,Nk&`?bFIldGYXilP$C1MV4'EDA1[8oMpHq F:FD_ZPjX'>a7(_(=ARSeai-bX "*&9TZORq.62:6DcMOFA(=NN37F]q1Xd)W(^L<Hp!"DQAgg_XTqP/(0CoEDhR+@Wnc"@2Wtod;\/moOnlSqf`VCehK]cI4%5&=`MN558%B=0E.s&G>5mj<,CZP$KDAr_[0kb7b4K"i#>= "[46g0F/0pPWVpNXUHgOfiV@&b=r* %s2?([p*jG7&re>C\qtb^_Y.Y\KT7GS0@m<0E6766[?_(c)H7JSqT67AQd3&0lUp4.`jiQ'41[,CQe2LU*.,in47K(`d/$C#"qCDHs4?L)rb4,H!]Tn7Wj<;j(f`rI90'$HQL231/4fq3A"cCd]Ob-HH"9`t?89AhYoDV#<\4DWdo0;9PT+9ba;E&.5&(s,,TFOGO."Aq\gn3-r\5#a& FAVPE(-fOUcJ$;*JZmD\b1fZR:'2'dS;fkfEh7B-kqL;FDp#s+[T'tpAb+cMk\819^86`6@'@k'mm!Ci3J1%T; p1TgG1mlKRe:C>H@N&lpR>_2'RG-7')C  35)H0R\88.5lFP0EhdH_FRPRRA/U*7op6<mg5ADOq[;NoXZ]j#\7VkPZ&I4"Q:(DQ(8#fH"?h ]!q)FqVd'`5K?h'.B ^7QK aQL!YhTiNYWtJ)Xga#g)1b>c@HrKbo(_6InOgZOL(I"d12 .7';]bcB=PA1\tD^J7q oo$"`"=AW7o5M#PclL?%Y>9P+/+4I^[k<,08C\`o!=?MQdHI]SQm$SGZ%r7LWG<f%IJ2gM@\mi[sTCrBm8Q*:8s^a!E5";IVAWn@@rXErsrRo!n^@WNYAn8[%B7C/YkZgi)F&2Bm<gS>Z_]Nm[G1Qi9,Q`Y!bUF5o);(q5rdohKafk-/)pi-Z/i#E/1Fpn&3fXEAl2$gAo%!9@*RDtW/")#H&jF!o$4HZQd(k#bT5]1qaY55B5NX*qAkh;^JAdlUt]tG.%AK6)=G>T0Q[Ld+$M;-U5mE8jc7%!QUiNae55V"1LMVqO%C001oeA9\UGglJ2QP>,]j[F?3bV&_X?N>$ mZY<\Af06H.HP"t\*a8!Vck8PR2io0\9!?[!>#]lZh*i/l(2m3%ZkF513FWEET;5f@?OhF&t6AKbYOn>H2g,$[\F7Do9-]dI!#!!=3MO*])A2L`Ii5)hV]*\n6;L4IDPgo.Rtthd<>HN<$:7@K9:!=\/0t'$CPsc(lF?jXTm*gA_5+X[X)d@EOnQjd8f'+ho-P7 Bo&02Fo>BaU<5jFKWrmm*3=9:M)U6<?;M/4c>MtbAX9_;cq$8eWP+YZ-VsB7_ZNntt;!HY5o0%NUq"7Kq]D`r<!6"W7$Y2P>Pf"%!@7Bj?nK.t6L%(H(:r eJ@A&)sjLF"OI/f!h#rS%lPRV:i3fhld]%\*;C9PTAJs_+F+! Srnq]BHjI4h;6AA&,7&j];Bdl;]X]Z[;H+.IC.537HVN.ZM1WFfK^o4aZ4#f:.Cp!rK"n+Q8q_@+99&AEILR4EF1*kV#Zi17-M`+#B-%C(I\ 8D`9EkPjJ:t@\;LAc(P6#%em7NMI9HhmZ,]@[#lH.W%&ejsADRKVa<o02ALDh ?m8E4d!LI9@S=35s%3#IhhDr/_ciln*:U4I;li$!p TM3&'#opi3#Ksc^^A#EbppbXQO$Vs*QhpQo[KN**(m^bU!P'dTk5<ThQPp1F"t9mKcj`Wjqe]#%h=A+Q"&IbF6<l^^&[%$&;D-bq?,?p:DpA.L#Y`7fhUd:XC8RD>!B1o%!RXJa)%98 arX7!r3!f($ZgAp%d:$9;8%Xd$1.a&kZEKbqS1 *TPbtBYQ\fY!Ct\- bBAt'And8N/Z3elFBm*J/J5:qY)A,o@&`f,<DK31#cY! F"7E(Pq\r(C+MPC5.DAqjth%nsOZ]`$*SjXap#P*-WsT!T*X)\*j?%dokd>q\Pp.fCZf\E5JB>&\`2H\1TP4Jj*&IZF`7"h7MgNVV)(Jg[2HC_O)ipS8<P&7^Lm'23qqO2mKKOngHAd&Pq4B#bOU0ZkQs-2UhD.DqA?JhU#%J;Ck$[h>L[^'K!lp3<O1XR?,K$MENo)9V*_"^bl7sQ4A2Oahh gh$%s\Gtppge(EZq:=3OY6 MZ1oSGmTqSL?ARR%= 3*Xf3g>re'pN*E"$M!GG]_f-Zh!]jMotT(32."?4;=o*"&Kks9sBRc98c=gGCGoP_=EA0R&B4;qAQ>95+4L]mP>%,$(6=@G-GO'* F@l>I-q-RqFB>?8@7<4Hb;(R3Jo[Za_dIN$=I'W*r-/.Rb&.WK*lnL`iVrlYa(GNh62Gt#Z4L^L(o>pkCn"oNI6sF\%0U[tLrdpq,l&NWt4giAdE&08K:ar6nBh&kH+>,5O:EQij+M_[@g5tM%TFAo#^naVFUEX `cEs/Fo-D5i(WNQL:4`WQ/&#LR%%>t 8).'fUYtMl?QI/3KE")l:.7)J0)Rr4p$Ui/?rV_Ui%YfeV9i=lGNb-I$HmR>q3(kdPB`LZf"&*%+"X*O@>nim?@nj+Bdd\a@i7tne0:hfH7WIJ75M*)?FUtYk?GXY/I"GR]gl/th[Liff+Q=hc.U&p]r<7Yrl07:T=\:(A1pltB8%dS#//>7%e;K_""NbN($:BP-i.aC*T?AmY-NM"_oDFrY3-pkL!EkM=ZFes&KC\/+:b?iA-KHX"AESPrS(*A>F'X<D,=9ih1FUanAA2`4gp$<=.g?TYcF=H"sE(#7PkcSO0.m0I7*.,GcKI8k]>)+=s/`!pPje] \"(EF'Gc&QT]n`9CM8W?4kraj?*iYB,0[FTt"3#@X(.\VHE;20 m#_da\(c$]3@CS?*s<ld9Dj^AW"k0$htA"BDK`f,/B.Wp=1W)LaA'Ok<dHp>js)U-m L[n3V@[<%e3-gC!Z)+_f8i9p.'p3 #/940)^4&P1SB#.66iPVn:T7c+/rtgOA-CaV$%8jEc$ 23QX9j<9lC[Y_VJp'1?l"577%U>>(HO?qmi\^\HFeU:R$Ik:^*C<m;Y 5AYX&!W(VrYMUnP876)sQjiNnbr3''%QkEE=?$#-&0QUXANki8723SiDB\0 %!\%6pHLamb3&eMWh^,I;,nd9MVKT``F=2R^09a0d.GNo)jj9ge)A0)k!,3gt8tKb4d(Ef_^H]%] H=U]9N)QEdsq24ncLar#O:R<Ea`Wj7@0s&q=5lD&@'nZS>@d?Jet.3@`=Ws::id[qSspkk6He;"kGSOpl__Dn@"!&9$IEUQtUM !i:X'G\LDpeEs:h1g4PJ]GmO@d:lkc^t3(D2WFM/l_9L5Z4#,/` F^&1:bXk9C_0jM!bdcd.j.1?s8O9i!Wg_P8=W13AMS+"MEf9j-'Q)^,o$hnsl@)d#e>l&+Qjh%hO=X_ZrARVQlT3N4Y![N`7,h_VXkEnnP`nTt\!\7!R:QTEK+'fSo%)kD0:#ZWe=*FO3Sic]i`F[W1)aY9kRIaS`@1_H<`hA9.#+.W^`V)Yqq2Hn7f:.2;a PZJEKRJAjQUq<?=9HI5>DYU.`Rm4*LX$Z >r[!R2Y*.ROnXYk?+]JJ`H/K6(G+(l0n/)tHFN%$P,R5_S]B?(AZMH OPbCX$*)T6"YjcMQI^B+; %:@\&+A$KTVB `M+)<@TZ;7$jggJ@b]V*[.jp3;I)$" L**>X+KHgQ*N&PDG6C[Ccs"MN-gl;jPbg)fdR+^_Ds7'`UeMn1,@a9`A:SG]UO]rCqXtQ_C j>AaHtKV,$-cN@D[O`?-A,<qk5cW((T`-%C_?A87T>nU1#!1Zd!R7nb@ZG6+6P''^ZhCNet:lR";8&l=3=6m'p9lA7m=Ht&g,?H"A`ah=qK\O]Kn=<N"1np-TWPq 3C"6+IfQA?DHK1""R6GYiaf`Z*+E1bI:@H?s,GA G=d-T%p1e3$h(gsml<dFK:q(1\RCIc`WIj938[tL;nc49'Y6MW#a?^@__*%(2IDJ16IsoA\bBH2km$\;I7#l5.;4t/F7"sYAJ'0sq>US6cJBAt?5Ti)Q8!K.MeNKn`nAU_Dh)=Zo_,R:>sQ+]O+tX&b*Op5*N__mkJdO*-+#n%3pn7?E 0A/pS`V9:VCi+*40;nXU[WBG]t=O2aDBU9(fLUH`AK(TYD( 9JJ/[#Cbm19n'3H,b(Ob:rprqVFfQt; )b&@WZ(tgah#SAJo+W%?6gh6k+*20T;Dh,,XpS36`4"6DX-nB$7lNq&X;b N,f)T?9lbGVFFL$B%9ofD5\5o)CtthNA]CWLAn67h.VS\Qp[7++]s/iZc,ZBJoA1j,C,A#NIBr6&!H>d;F37(A59@btq5<V\04NCBgA*L<BVF]>./1?S;.F*94=?6@PCIln`M1AaBoge7C18K%JS0m8_D;ZQ?W*4l`1Qa^ [[[^SG U%ZMXP:.4>FpGV('i@fZ`bD8S3<Gr#eEC%j.tL=l<;\0e`p&`)Yc?l/YHRSgDoktZ[\-N^4k1h!-VtPkY%WCX.R-^^Bf"Rr\^rB4I[M_=f3Z\HS-=[LM7;! E2*2'N'D6H75D7M+KZq>4<Q';J(")%BkV-jk2c?RljcE$Z"!FlS/( b&k+e+o(3](Mj=jl#is4A&R*Wda-UVGdA;NpS/NCB=3Z_m-+fs2s1C17;qf*]k:*EYe-5)oAS=%"g*_\pXGSAb&doD0.f\SUjKO?13_1+9X[\=KbSM!0B0C <ch<&3,H(JIB!!g)!>5PtgN( m?%;gP7rG"-Y8,aqtBXne5"_7!*0i/hG&jNV7V5FEGY3TW=L$^O2flhW?7.T1["^Ef+fk=&h!JSi9J_+t226p>8K:`[l^[&%AOI)oI1AIE0<eEmL^M;pWhmi\dE<^$r(2Th<.BcP`a#mM2X!8oAi-(6\_(63<4AicTAVFJn6XMIQ]'m7UaPbb&/b]M#A`naAB':@^l3EasRJA6Nod>A@2mNr*MKAP)W$>l-,.s$614h&b:hW@eWaO+qS7/`)EZk=P)@UtjI)6G^4DiWRB[GpK)=:&YY @ElO5-P+%BV\8;_H=0QV*En\TG%_YM@@7,c@%[3TDLVNi33!2i3-p4UP.$i-653qrVn0&A0F(n<YXO-jKZjVWbZNRb(\U]Vt$C@?AfeCm#KP\lN:B,;8k'T@G/l@l"AiWQV5Zc"E%QTe$m,'LHMB7ht3Z[g27pa,_\(<XODta 7#f <gZL)LF"gf3='a!#$`h(ieX!AYW)A:9^KNJRAAB"1q(f0J2kER"A53,[G*8Ds*"k^`IU\FS^7^A"0Kl?9*V_LlF#Y<4NUJti6ZV_MKf?p7QB5SCdk4`j>)8"#b@\$j\\o1L_GY]F>reb8%k!A?W'7S7g2GF-4`  .`s]H$2KL[)e$tW$4%(E1T+go"ZJe6N8?ftd'!F'i(IooWEIOCo!F:g1o/9LP.M+R`r#[P.I(-S"bhX1mGIm!T"<V39KCB'_C3i,k6L=8knE[Y8Y$j5rqHLAM[K/h2R&2bp&0Nt%f%aG9lIc8fWNQL/Lq3ZEWOkO=r79Aajl'^a-T0ae(+-,.kgTlD7tM.cnqSTX`55tp_aZNQM&k)?maA8L[J]Ye6NH>5tPm0o.l/SWe%<(9$pSDml_9JgoY)\SQn6:b_>TY&5/9_BmY->iD!@n(W!0\2kS!928^B  Jd%jKS?l+S% GiB$Bk(N74jEcJeHF_ssI[&E3T\R)NE0iqRk^c9>t H3MKKH0FU73U(MU&V\IW\F"A%5";[ri=#A`oPY$=Vo=/%il;!A\*D8_dHL%6S)Kk2IIXBBY]3s9F)H!&$ahAOhS1?18SY.b@WX,.\SJEfbI!78Xg!U5(=N<)iYWOJRQAEIi%s!#CN_[/ 0#aO\7@2jepFrO\^ToBUKf@74VT_rg6/_:kZ2R?,si Ks9_oZFd:A/@\^r'@k^mr'6$KICk,F$;@P]1H[fZrfpWFbg*,f7[Ln$4m.+(;3i:]/A 8#P&fU/\ZI*\O@Y)ai64fi"#_G<@4N2>TD<FCfh&NiF"0Q@F]n>lRMe-o$A&a=l9JWtY:;*5*L.>'rID!qop(R=f0SD*S"0j7Sh!@M@HWkOBb+QHbL["*.#eq3,j;Ri8sGq:#6JRj)Z4?m(WtCZ@DHo>W$<(=mS7*dI :.f$X51B9U`"d'QCCr7s1E_,GfqS<i2%/W+NK2s#;;t]IILa2[/d1`W[FeV14 jQ61aU,_.r#od,%'0l`e"FUKO/FJAiOYKD(@1UWC@s@,d4n'Dg\*_;/+*rSon#pdem7'\Ss2H)R&XK4Gqc0;V]RAXfmJU:)mIGA)*[LB5jnY1FArIG=.%AAY)"<.ZqopOfqcT<sBp@#0AmBA +hH`gIA/= %LL0mb=P4*rN X,8B(`7<eAlZ/i %j$e4T<EVEqJpV:FbAH@.K/cpAnO&5>)N4Q](>[:4m14*k/'oW&g")9i>F=mZ3YL=">B$=T1O=M4Y@AdaI7\)23KEcM%-B5cQ'$lp]g\1LLm4Do'I[[+[.KSY(hj,[=A'QAHtZGI)iSB8.O-pDH:K6Nqg_AY,aaeWo;9&.Z6!lSP8$<M$SlHA:C2_Ns!3cJ<EXmEA"O+[qEm:2IMjfc aCEY!nWUsen^1:r3QKdp+;p,P4q@42iT4-h,X[Flksgt!lW^j6Wk7Z6A;J/'04NoL.ADW>WY?%Ucf*l,m=.J>X1(+=ro)$hWSRY<[R*ESAO@kYE,+ZE=B12;UBgB[r.`HektD.RXZfAd=6tMIr0mkAgXrBbm]%hJ$Ia>?]p]>.5>a;8!ZLoc-eC(KB?3(+^o^to+Pgt:LT4Y(A 70sos!rHMEpW@T [=`SA-,jTCB`(HbKgY(!]S=OiPMRDP_kLd_V\?s`^* a,OXlt>i+6Le`,t'^_t[@1,q:dqPA855MEc4&m65\1j3n.+<sp8IH*CT-?`Y20$k,b;@mn'HNlA`giV7KUI!29;YA"jZd7=Sn=nGB&`+D=Y@VMpSVK/cYlg'hY/[V$i']#t(?\2Y=s'AnDPf>_J0-V 1jej!PM4LYrW],HA]3GAtLF*c%NpR#eAK7W@.CD08 .K-4QeTlr2A\R#P6:t;npdCXPmE;=M)H.Ao2ki.Gk^X7OS?jRr9I4D cg7U]'e69-f-Gj'2(h*.js:I%FpTdhnfDI MNLcQk7B+XY\AQWZ.M;&N)l^W9g*g1)O>cIh(t]l=:g.8MNR[^^HpbAEKhN_VK>=/C]'e@TKAiigaOjofP"UTKJ4?g)N,ro=C:q:<=Sfg4pO#BtfCrk^4*<$M_OI6>\V)"m[8?)=9K.!nH_\@,[J\l&$o4ZS+W_32GH\QKWpRSPo\9ST>,*YIQXj54\O<K@R9ocIYA#a@n!X8+IUq'Dg>aWT+KqQg#rCIpL%:/^A/Zk0!&Q<q;0VN7$2r`"l%Rp"dEe3+4,;AIjEm'f6&qljfXjQEAWO^S?;7HQ%*)0HboA8:WLUpX%dRANd:UE\kYPfSgD-C\,dh#E#F%!c/oYfY^Ho]#GHD#;ZFrAk==(c2Nq@ !(]/FTq.8Wmea XJ-@,.X'9r? !LB&arUD2Ai;LjC*KaIA:EEK-,6&'6Y)$jYdf=QM7Coh5fVp]B#/(E($(\b7"rZH-!sAd*VRWW(c3F6 :Jl;'a\."VDJZ"NsMr:30E /]PRT7d.H_ma1tsM&UAI)q!jRH7Aio 1=IANt.Z#3k[_'\3\h;s@nCH/2T![ZJ:aBgUkOP'p4pEPNU-rAGAk,:_+nFm,:b/4AO<b+rIA(.kGt2b\T[d63hjELNXIVqajbG0:HKY+W>MFDtt7ceOoco(0Z9$o:1EV,bq!hT7QjUBK@FRVXA)b#FAG<;c[Ad_&R41&&P<CcTR'taj]EF(fCsFb'/$Of?@1M$!(.'m:Kb`RAXh[X9IHp/ ZG35b.TZjN*!hb(6F+/qUs'@A04<TqGD?%+3jI3`q3ojQn=%^]-PAZ&m+QKl@57 )!p0>ik-#?=YWgjc'Y$)47J*>">o<t:b*M@6a!$F=Zfco2fWiKB%P,_a58kf)'UU>U5nkr'tNTC&bnc,nG*!W5[`8sfC;aF+tTG8t9>1jIf@nOAaEr]DU$chWZ61 )fB4In+i<.]^0af-pJ/C8RlP(ZA`\mP;T4h"c[VMr1X1%fmdpk)4BF9#i&*WbY+A OG;2"V'LML,qI>V4P@U6H\%$lg+D>=B(I?-Q+-$Z&+#mL8f UffC2&RTX"hk7eYXi,55tjFO41th)'T*cSD/\YDiRmJ&4lQD]rrF88apB\qZ[Bs!OX64<PGR$adA:GTfT70q[W*X^<0:S_aiHQsq2%tT3]HYs%IYU'm7Ke\Jiasl258g>L*9lPXApK`SIA49YYMr/D;%*1]8G1j:A#o*MP?N.+=4n=(fW2KLhMD)CQ000_A%XAa^n?a1!ts1sg/V7Cp-:6[fI(YQp*i6AJtf\):mj+)`"[G=P9<V;;`KYh2jW N>FVQJ\H"LDYi/<\I#aKdnn3,$eeltPj#iEJYG\(R[*.s&U!KcS).Vm^tr;gA$kc\P\?=+AhU2%V<_Cj/KS0sZ4^QR]pVSZD\:is+:-GUH8i4HIJj7B:tT63-B_m9K>ChXigVt\MN@BUmBDig5A)4?;TjAPpW>6Ab(jdh'\!lF&IH,AN!Wbq <nI @GWt*"^a%HP@8Rf2!7""d4iC"0^"m=kQpiEEZ(/lr7'r&;@2IY B;ZVolI=3<cJhn%@39A4G<q##4n#j(Vk"b*l)$q=U3>E&=ZeNW6:ci%"_Krid<\`No2Vq^]KG>RW'C63MXS1o$(jWI/J>Xp5=N4Ns2S4d33ifOM1!A$&@4VU$1&#-btCrgF""Ge^MR<s0(HAAiJ%RBcKkICbShQT/W6N8D*6.[UlMh6nU"YgB@FZK4PX#,_o<p?HRm7')7gPW5QV\aWA_,h711$_.0nhh@&+=-)&O<>@TD6)Almk!ZgqKC8OgppkZJHl6ZL tR#n,31n]$i-)AO4)LKM?<K_e`hR(=^5@tmsQ'Z+<'#ZiNL4%[iD'1`01cC?=C37=KaO<<8?.A71,QMVZj%EEoZ]cF".(ta3.lA5QFllF(HEYg:;4MqAAnZWKqd agd>bVV`b[*A.k^R8 9>/ZV+pP(XNi),k(\X F2)T9;*?$9K"-l^#K``8m<@Rd'\LCGqshA9FJs[2Nqiik))Ek.M fgWa[":])lE ^igSa+'4FQ8?O*(DBWH\?8L1qXY(h?k,=i*/=_]l$%d$*cW+5KP87`6RF#c,1r'K6Sg2=&74Yd@7,b`4"95bD(e'UY)YR#kX )A*9.q0sl,j)R^(O'5kP7!jMprGFM*!r5A]BJ'&pkPdeO@Q[B++1KEPLJ0`1MbqoS!GgCZ]-)aDiol)cq@5bkCAn*@8 s-JT!R*mo7PX'&]\A&Cm)F8!1+a!rpK6#dO8;0:gC$?XEb6N.WQTK;cS%KF0*mraSTAP-E[aSVO@7>5$1E##aD5&,aIZTkUE%#9W]C.5@=8(/<XR6p3ksfh)NcQH^pM?s1D^4XKaD%E7f>KHW/t.iDZ]QQ5I=ErFf)HqLV_J)#X&FbIh*QJT[A_Os-/#f!Qgb\!KArLj!UGN#9gl&k3*X3/g;:n`dY-!Y&#RZG8Klc+PSQmQ:e\BMCgJHQ\Oi!jVO!-6g@A3rmb\pVq*B0@5r*ktX\BAdl-L,@@GjBGS7AO^.!jU%icc-^+@!!nTN/E#9)1"m86qQJ$)i2^"<E;V-I<Q6h@)QV4pQ bUcFCU>e>4*h'&'=kETF-3I(=5c7,bqY5Mc5c,'R!n0hr87*phBM:%t(44jM(!F04pg"-R]DIn@"d`'A4##B;X9d`,R1S%n boGUpSY!4helQV8#69MQRj.(fRJi<;'oIhK&Va@g*eo/k^3O+9tOA)V>;gZ*M!CGYoA^Mek(+p0M7AY9ZY:sS)&7Q+(h+t.NRqX %`1)dh4q$.Ib7s ]SGKn[Q0h]mm+G3IUS@/bq$C%<#2#k9scGN*V$/6gL!Tf@.FF//.r5gBY?9D[#mGbQ+paH4rlVGsXXBqJ-E.ZKeP0AKQX(mPh?W_l.X\I@UKb"rHrQ3n*5nk3L_jA&4`@SkL/4f&,UYsrA1\JU75X `<2QeJ(4,(s*SYAO5<-tNh>V:F^p135lAmDd"#FA2_U@raXOmOqjT&=IdAoa"88UD_5e*=7Yib-q=ier1/b>(\b_?%D)kh(A;A,9Y8ob.WQbi'S@QsRf`%C@%F]qsbq-e<XP661H80!Oa'Z<\1;4i[?l[BQ9GG6%Ds'HT\_`@)4n;H^aCG[J?$^N.)sEgR rh5#p7bR(A!8t5nT@c$0eaP35JL*U+A`=Wb$AgWhm0Y7)[]j`,;\4Adkst[$7Wnl;M_V?lonmaePN)HK5V"g!nQ=`"gpf<B2U@YWj)jnIelhP8g$6+g:Ft&6jV (n'BmCD@t$Ncg7TU=fnRLC!h3DFk"NaVL*6(c\kd%Z>&il3-&s/`riH3;+8M7>am<sT.R>MpJXI/XoHAkPKpXJU71$-'?>eo:XbD^N>1J]NBq:Xj9aW8L4"+<Hn?p+tp$R.>\f8[r(Nk3AB2Ca3:9<OA"(`D9l2EmmQ`d@Lj#HskG@PI5F&ckNnk4e>M>>(>r3ZP%S7K:Jh5'_)JiQn"2_ff6>#0K/hh2,*,dUbS(UhFeRsr"ZO^p*qM'BW9p8 (/EOjJqM<[pbme&L`2XT/b&$ 4R[GI8.6ReDO#/HEA.2Md]DH0<_YqiF;]mFEX?12oq,NnE5qIV7mM<hHb+PZ`GS#rUagL;-TN?lI!kmbT_,CZD+\'*NTI/%LTZL5X_gKd*DRd@Ve8ZG1#fcmM6;Q'hFN(@+V;9j%NC3 &]ohb&X$Y"W[/'g0Ljo3lOIDQ-U4%%"#?]g3:dqA53k+8tAd!aM(<N,7-Y7+'B0VJ7E6B?MRS&Zj=*ZU;!S8a=qA^?g<?<C\AiRF+q0\?f#bTcWpB*4:`7JAG(.rMHmq*5A8>, k+a*)D3SQY9*9!Q?=g[m!<K,<]"3`"(l:>mTe:jmq&jAQeCad4Wo^c34ttXHq8Bf&_*11<t?E_'NI6,6N9/! 2E$"Ctc-3[F@`:+9f69b1o2"'!l`o[iIP1rgX&9r^]a58n]%/Zo^XSA+llTTYEGAelN4D_h^,.rndN(=&AlntlF9R:i6gNf;#E8@Ni*:3]*Y7L`PPFM">a90K"$Ti7V-LCJ$_\XHOUe9';=>pfk5TFBpgJ.\<BA1RhL6Y7^tP6=3EAG=JlK\e<Mj^a6c-[d=VG/#L-djIrjB._(/KosS>`)$rV#[kDp@M@%)Z`2MQp&=kq-T*-T!`.D7*e*_BM:oA$`O?/,$FB>,^7Rb<`>?QNp0&P?HH\6e\ZW"+]M.N3GfLPSJ,&$<b-a.?m4LEMbt[FH/.LX%]!'8S<`kL7H'S;%Bhml-O%#A.AQ#dl$+PXE8!Y!2%aCt),+ NK>UHZQoT3qk<7r'RJD9oFYcY%X*LdK5l\M=VVG%Cd`1V;0AV:/@.GP@&;pMo/%70[36V@UbeR/bqp(aA;/8, h3cYKhm8-<pXs3Jobn",N[H]FSfKenq[78f#4Oj74\:L[`O#i=?Un2tmI/mD=po'i-,0oBQ4JWjP=9">!X>`Ak@.=KF/Kn*Lr9A2HBMb+Ma5=6GlaJJ7D)VNsYn>kS+[1W!rF-2=/LV(7ee-LM%)b]Xf@?MknFlJ?6LAbX.H7toG'U*ZhALkX>'`/Z:O7Asj29LgT0&V!+/ABRn=aEK+qI\,oU0sMsfo0e\[YXY]+Spbn67HIJOfCgJR3<43tZC1KnJr=f4fr:.#KRfZ(M=;!k;@HT :/iZ_H.HTPn2VkAnn)s4A1'Y]1iV5#,mI=m`^(4@+(`^%-ia"oh<N:@Nttel]\]Oma*LdIdFt+O6aV/t7MJ0c&8Q%M`attI'R0ij3hasMh]VJj?"Hiq'GR4MWn5aOt-K+DWJ\!\mn[?LXWA?MRs9 ][%Q7+=ZfN>6!%g[_/D&;8!':E1NKG&4))ARR-Ar6=)@Q &&)>/f/=SLQ_#,efRaiKj:*4G.8Lc*>*BkJi#bXoHQr&^=aXB0\-m;?\^F_<ZnUT1W8IsdIVf#q,^t=o*%PXj<dN5W40HsbA.FdR-Ii&0All\>AF?r5oA\EI`X23a=8RZR3LqN#m,VE5+C,"Lhs*mrmFKG^(4ffII==VkpJ"f)T*qO_ja9,\J"-Qt$"AClXSUTAc/t[-dR/?&fV0E3r-D% ]M;SGmMo>h[H`iA%a@.N\D+eh@*-`Ap##HP&$bIY!-Cm14pK7X@T)^%b'bF7M`F;)Lh!SN9FTG*dY_rT\pK;8A#6lINMYs+JGn9Q`?-oKWN.YfE g^?#n@ZFI8"a9:sc5$tKmD8o-;CRJ92+Y[3cAWNS:Jf9/T1#Y=F-64BiIRiQB3qCbIU</Rr)T$iV)q\ r/cAdd:K^;WA?b[b<L(CpHRk -&%PVE8Ng..Nfc_k\Pd3AFA()<3l<4CWAs FcSbb%$j6WEZ,_)O(?(&)>XX=p=DA*/j=nrPcOsf`Ja18I7R=_(g5mABgVD<M4EFPUE9+ *>3Y&*>JKP')OWdVkC-fRrPcX0KMt2 C`Fol[nRllZriSWs']A=LX<3RPV`?cBfY#-A:#F?Y[$Y$5.@2sW7T?L`$;QH$$VgYkr4B_"eSC[a36dC[ cT%*a(C%<%:X/_R6Fq;YBAgd 9)lUFXg$PtnA,"EQrAq;:Ss+tA"tF3VA^7$\]/!*]2+8/ ,0ES-1??Wq[>_$`;2kf8^lt-fZ>h[#5G>j(BNG.'Xqk]?n$cLOOLhU2F?W%MOLM%JsHp8GJ$VO=3h3P/*fp1)hl]iP"32CFGM@_$,G!`KHh#d0L"5EeSn hj'.3Y06q`#_%Z[%7PZoZ;YgN)b^@&'Ym_,_l_q"#)gK(#6U`k7W,ie/W_)a/Q;r6bl<q0EAGX:^.P@Ol')E^/@EPPjaHoM9JZjC6+ki@J^\q/'#sRa%H1WkHEG/+9%KWamAsUdU6rp'Xo)@@E$Fq"KC`W/jLk.Lnd'CoEcA2N36E@ENT8pI@9J:R]^O3oN5YY,^ JV=6J\bmaR8*A0)&</R(t`/+(NC[(6TD_'6Ul10n6Wgd5b*/A1`$fciafJ/@*4UY[[0[N!6?gC389H9]"b]<ltnA@.QYJ#X%'hq]&BX;s5d36g])4Oa:[0+QZ(MQRmsKS`(r%&mG_2NpF"ATY6EqGF68OB05o0k4BU&DEh!(.7j2k>-:@2c]KGGY5WW iKLZe)WWjm 0:;Nm[dF/$%U"f:DoeGgRmY-Lf:tf:a!7_>G!lAB663CedhibAW+PYF-,_"26:NRO@:B8;>dBk?Ej(%NHQ_2:p"5aR#<:N6+]b3J4$31\a`B-,B+)M\0Ramq(XMV>jNKA=Kp%lXbN+E;#EbCHsaX00jg.iAXL:q?\L#1UFRm_%K]h,C%9mo^h*Q,14#^+Z@m<FI3En$:niO.5;B6l,5b]Tl?.!cT1].Ke7SeQAC7AVM^I4U,*>8]FqVtFL\BH.m$t8SqGpc?nHLlMJ=@.SCkXhjE5-lqg= BI9Rq8PSf;LmfJTa>jBUaQ,p\,7V]"4jf@dT+<ft+"3 ;FrUmt5`^<L=h55./CFW3gt9r6ctRCe6+3lZKs['it`J5jFH2@V.7JA8E?RT; UQ9A7BoM%*@2eE![bd\5p9]CPGK;i 2EDGr4(Y_T2X5mef,sH0+Ei3*gVD3=Y.@),$pWir3YV<\*)At6DqAm``JN/6Ld$*nRPSApMdsB^U'RK_tOiEle/XZB5E>,T(r^B#)gk3*FR;'*mq5!2)@N0AK/.`^1tp_p^VZ1,\O3"S]qO9eNQRo`L.eG?/f7Dl.2nZYpd aW8o03SA%ZDLNP3G8*1<6:*hVoJ=TrVa&!t(I+DoLW6h0tkmAnehjg+>UJV ]JTBnm ;hN^l+)S.CG:\j[em6m>;TK5Y%;p=>H.8ZedEk=BN?\\DOG)PP.S-!lT@#&HB9)FOII[CO(e0&JL<O)gX-CiH=I#&q(dAH7$5X'%\G.N,75ogEeb]LmLS0)^@=qAgZ@e+De!<7JAY\#6N2oT"=:g7k\S]?WJ6gM"]bJ.fZ>LJ7V=d(Lr:=dm]p3"SL;'*_O)"6V897cWP$s>Q*<?dla:j)rV1p#KDA&qj.m>I\G*JHZY6/9c[/.!:31'mibAEiEkRa_%]d+?)bna.,ZIf)cfc<L8j%9X.330t7\oUlh%tbH3'kF`'8ZLk*r,0`ZTOo\]AB5n$^D+3l]dNfPS/c't#<aT&Z=kd3Lm\)s+?P@( /^Rb@FK"Wki]h7XBNFMt)lh@aGT%?CqHV*`==Hat#^4!DYTn@Z>Chc;gFc.e'[)<tm]r)As!Akq<(]9<tiZ92SA>6.eV#/itVK+:Lr0HC3$Z4*oLk%0mYLj3#DU\4qWqNBsNS'_B9d-*09U9),e'>bYi?#&dAl\X(7?0%eRQ:V*hDeI84n"X1a/N,ITr5/N,S2"3Pm,k5]s5gf7WU`NkNrdFd(7P:,)(nPD=jH8c4ksI/<.WUfE=_OF7Up4H>qic<.r05nsEoeXfgB2$ ]MVSj5Hj=GsCs"\hA1>c:9Uj?%[Y=<N6*`QE*L9M4K'k@j!eYC/KDs5AbA/-ATEn5F*tG:KEVSKsbc%TMC"tV]j!LA[8EG*-i^TYY),3hZ1tlKbf\(Y/o66iNjIW-_g."piGg0kT7IlVDo1e$ai'iJ 1k$Z%gJ 3n(ZmD1X]IZYZgHj_"hP-a)N5FCL9c@s[j-9SF-RAeDU)eL0oNT.\nXZpe$,ZHH-:ch:.6:P"cL(09m#L9&g_F)F`kLBfC+n&`MaONb\L8&'XOjW&A5V!9FqPYk1:i9*J@<RV.7Fg8dR[!($0RBG8JAjk)CT^*80]\.U.Ll-<hW(HF_';i9Bt>1/=4<T1H[tm'@W,.^J2%)fUBk+SZ(_5Frl4B;#< @<n&qeFD^ 0=#81[sSo8@@tWDO/S#/*`Uh+NNIRRONqtgb$>jA^TCVaLePTrY]2IlGI?SXRiA\0loHkLs?`O\8&?<>3!?SM3AmB)W>oRDU$[2k`7_>Y,a,+C.e":sEb&fTD0EA5.XdX2#ZTM>$X93b37.*$+YrFTorc85839WA[A:7?4>X`VIN3`<5!ZH\h^4pFA<mZ@[c];\6MPj.#c;3.3@6c;<p\gQ9IAH<i;G+'l_8>^JAln:8Q'HFG`jnAnCRf`8WHPF]]$k[B#1;LHW?)W5IS4@C=O$4E"]4!Cl2GpA ^Cm/tJ *?`6pLMkVdd.iMlo#[/<l\b=JZN$S]G]#Ee&/pd.#16olAklO:s,1e+9d2;SA 'j@VP3BEFcAUh_9Y&Y!cnMsh3>af]Jc#Jn^tn?BefEJ]jMMkWIh`]sha.f+e< 80^_)6 `G0=YPUDm_Efb*\&*S?Op6kBI;Ae!C)-(DFT<q_<TF=+ei,8oY5NDA+1r&qr p?''<`Vnp;SU#9.>>2iQk2tOftCQ!M8V(>S=@$RNZ*n=ANm2B1kN#I)PC\G;\aEHjW#XrRo">"YFD(`pU5tf)_T^8SLUZqU#.2C6`#EpJtZ^KL\.(n/&-0WWO&mr`1RAF"&LtQ=`<h6?#:aJnh@H WR,p@l@+(&;2e]NC?cj8e\'!Xi!^7=dDl[2^QfrrXMM0#aNVXB9&Z?02.^4AT#Ln;QLCcN5P&45B^cU)mg.,IJ'/gN7?>i?5opDmm`Aahli-r,H*1(32^Lc>n<,]]-^]0GRn$l5j_N#hr4;*.e6P?-$+Sm%PU>9as`Ls1-JINC"eFPC%5sATQF#,s`I;SRFCN@:- C?R)b:tX\:iVpK<`0FR`].7k:KmlBjI[,Kq"@QGa*QK.mkd$CnOp$5WW@GqDZnJ>p'E4,/j[_hX"1@)O=A>`-Qb1Re+b'!': $kU<W"=s)AnJ4.:4&'S&IY%#CbnJS5;_`!42!b\c*%%+"@F^n]5PfCjORH.-^?_t=:Rd;/lb=B8SjC35 (?e>B`bgrrJ`&"9V7e/)i,(:I:7j5gh \,&I5>&h/^C0PctX-3s'VAdCB6sO(F."4:OL50H3+o("=n.AU13=OsE-Y$8a0jSp+!3OS0Kn%TY1VjAGI2EcnJ/f,9?RRWUhd^AHAcq=%NF"c_O6\5>lK<IKE"!6G[/=OP!)K]mIYCL_T*U;BmBtV3[1j%_t"OI"c@`#Ib2mim6e*#KG t3Xpsq\MlB>L45A?.jr0B.]XRc(?7?6MB0P1VWEc1n!'/N!75,.=!D>92_FPLHmPDB"qrJ'BK978B3g.6(Nh/-#\"SsokOb>DcfJ^eEa &.ccAH2_bdA"")'I)7Y$3o%@l]RPrAogDj;60"LXpE/VtkjV[%4rYh0NAs\a'_0/Uc(iVb_i%<A$qs>?>[GTP\5@9%iiiB6r91qf0At[t$D-_:5^M_7g?M_ZQX][6OMK8"S,Um8@S[Z3M&;ZYT)N&_LA.=c PAl5A@(\5jB(8O!t% c$s?+Ga?,JjP.,#B_DI8,PPjK+!e"^dqNKdd[jHL'\/_eaPifs[2CiG^nm:.gjV`&qak@BJ0SRVSQhtQQ2[A]?]k)o`lln\^4I>6*SfJ#tc-'aqt7+?h-.Xsn!B*AKV25a'NH,j&YQ[?)@PK8L'PZDPtK>n)+F6^Nnj,ZrfpjWg:H+_*>/6K_]a?#mn^dAa:8tDLa3hi2_bZ@rk?g9%a^s&eW_#k!9Sr(mM0CQ2Ot`qnBfR2Pm`8hq6"g#E9XNF)th%(IH=^FM'bso!)n7Jg3o?\6mQ#jlI0GU5G+#DmC(V;7@(^gs(t\mJ*V&\V\@Ed[b2[[>N^;#SIWj#Af-cF!m,=1Hh$R=VSclKEqnom[0,QV-s%K#!g9G;4o@c^?;D,jRFHaaCUh-L -4\6TX)`\IB4:4(+Adeh9CQf=t0(tO>n;C@Nh__?Fo&Z8]TO:hMf_+B D8?+=PA*bE<M'6@Y!^eS:G`apd(:5)Q>[JP1=Hjn aYs>SRl"ITj4qL)ILm$i\f^Kmg)atqED,]34Mt+IAA,%Y ignFm3&[4rbl6#c9+aW9/R+HSXkAA'.Ij2>1(OJWF24H(SBY^;V1%&Ora?U#(mr]de`@&QJ&(^Zl"9%N"`t_[]E98>c?sGjo#;nd*,kW=>r_Ddt!Q,Q25FgH72eL*fW2f7E+<aAn<gZ"PaYaP'p* OE>[hihR;bqmDooi9`jiLm)PM-(A:i=D2%P/MB)k@'dTBLX@:EKK4`A0"A)`1LmBr U$ql2)AtCmUsDiAVAWb8""#kV=b65,&CX!H(Da7sdd-<=hHHo03,OLCcC6* \?(_T)47RfWfPYc_eZ&%1lj"0W/?.=J?M%orZT5<qA51WSnfroD)`ccg-\K:+HQ'h8E_ALTimoeA1dXFP3 CI/c9_0%J]DE=(Fa''lR4<9B\'5s.2Co580Sri[A85n<1ro/"#)_/-A3*),@mmp4UJF4'j4FM[tc6Kj9&DeB<gH7=1AIN3fB):e@@jo\'-teO;2`M!P_Xga'C]U#mSpV(CedWd6/:\A*k6_3S'ca? $hei3j$_8JB-W_[m8oDjQ++m5lj*moJH$3\hf_<92:eg:^?Jb></is_#l&CL7<&b_U7Eh,c]4B9j*!,_5pH3<+BRc+n2 'AB])MT\eb\-XF5X^+-2DDJ7 FN&ra,T;\97@l>?9C;<TElZRc'VNg._V'Hio+fm]NosF&s(R#$tOfd=LdVt X?8E^W /fMI41;Cj]e9$=^m3<m?O:%11F7P7h$gleBj+0!^0=;BE+4+`Kh8Z[T[6prYkF%]_a5+-pk 4a/$BrLkY>#*N S*4l6*R_70:fP>"mlEA-#DPXVdfF>A5JJ*\Lk&!.@CNtQLn74,gN_NK=h'I`RAc'Kt7^AslCRjMGc'j+[,W6$LbUJ0@GLd3FK)]81&P8b]DT;@^7??c:NA]8ptTrR&,/eX)I]MK&'q%TcPe(TaV-er!'3j.iXGAmdG3$GZ&G$')>/AhbOtm2T@hNq\\sfps -L248n$^ALP]ho[@1/.ZZq3IWG!*2WXPs%[S-$**YGC?($A-;.G-NOa>B&)A0_.`Cr'QlM_=>GA(Q%Crtn_6Oi+pj*iq@eX_As'nS U[LJtt4p3Dn6FHIY(1I%D4\>r78crA)<OVqpHbm9k!Miiis $I[O5\HVS6"Tm0L$Z;k6AJR':(]^c&C2)_cALI:8^P: GD+]r7Qm<mf*?3@Gq8 fP%YFr=JB#3j"[I7FM+A?Nl2qV((8N!ARRZEFm.Ha_C-"l]fTJU'-eD/+().mkYJj G/":CE2NM_ngf=(frO3NW4KfN@<%"ltQ;6`MMD9YUL?YdKE86Wr-3@WP->E4aD#\hU!][mh3)ME5bCo(OlVLEU35q (fjKUlBq^qCn[%N"WAV_8Tb-EA3IM]4S'-5\phTYY3SFsCn'( F<TWXKhQ&!Q,Nj*!o"],M5_YfG6*EHcZ=P(SiAY%1CZmnIfeA;Fb(hIdH3WA#$?mHK@OFcrF<.pBUQC46T2'?qr5`>l<(cLB<p:*jo5FDVd=6+NB1>=XG#rVjK5P"b9%bJee_/_AL>D_Oa;XZs\ JFHRP"n+.#AY^.$a1p'j+;3@Ho4^)W(C<;J+PfKr'DW(qKn/L^lB@X`8[9\.$#i^,)RCE).`gMXC?p_jh`.d5$<VE<n`!f&b-J2VHDmgXs_2T3c<84Q`r("Ua"om1.F8OWPc8f.CJ=^n9MC8P-50PhA"P2Ibm_EWGs*HNR)+'Se-;#X9OC)B3DPjO%dabK]:^VVEmM*6_jG)P\IJ"gpKm4 tp[^N6;6!FR!nVFT^<gL3%$FM>Vb4^h\b;Q5LY&&7"BKkn ]$^-`+S9M'=!f:Vh643P-OraoJQnn*@AE3n3%kcMt"dh'CRBK',l@6`?Z)M7_1<DOZ`[K3h1<.FH?lc9-_:Io&d2Ta#SDr"_tRBjI8<co`QL/Aid)lOYW-Sk%*eNch3K8`<N-]X0)(Q!`HVm $^%LB9paS;qK Ad2t9c<:BsC!g#NA)V2IFnr0kAZN/..P0 $B=moOAaJM*<sqLUPpnHK/E5-f 7YM=[F$>*3gg)].<hAk\,72dH`_2'eP'36F5%pQ8+:FH'Q:;2ZXXGIApr]q[s65"? XJ g&r^=7K;G+?2s&->:Vad("+gft$T3aW]q+3o(d/WcSW:_B2#e@n&mq7N7W09],V[Hio8!6OZ%nP=LjAl"]h1@&T`8XDF-3F,%MD=.Y[j8#Wj6>=8;2nLO`93V8HiB3GYjW4CBdeI<)W(SZ8cm;SCGgC`ZK!$)Z\CM>W!Na/:VK`MA[-YdoS->HZ5Nm+^R[W^NrOI-(c)J6HCC7e'M=-DaNcPf]4r;rTdl\0[>6"\1)kHV,IoaP2\F!PJ2jL1G-4Y?)ML"a:G^^/EkX`>)@_#r$TZJg6;A7YWf+rJ5hec<&FJ@?3%;]GGmB9DmInjAY@^AE24MZ2Sb#(:!ke1J3mU0'q;AM8XHLgrj3<&Z-]l!M%2A5.a<RYhIK[!9n@8QDnJ6=]^OVR:6->f>ZRh!qLr)MJn>>0bbDLRR<[hq$8oi'2h.blNaY .N'L/'h[&3*\Onjl/LUoMjA= FQj<2l4[>JGsCM:`Q:#[QL9/U9V>LZrfl%=9OAtLg3.'eLrH75.:Nm,i>Bd7 3n<2-q8p=?`FM"Em6g_ngd*WND4PtcgT)ecQe%d1"8A_(qPr*iW9N#="aBd8N3bKONV* -p[^^h`/C$Oc[b':)#W3>rBBtQ<;giCQ?/kSK'j.gMK8i>6`c<B'gC2D?tQdAFOHra3TSQ#qX]a8!3GC)j!35KLV,j#]OYJ,c*E-^&OFM[0,9j)sf&ORm@3*2tUcW8T5%c"OI#-tZS;=+5j#0#4GPAN[,E.ptI+g/BX_GVN`/)OAA&phEaYAT*UJ:9Q%BA``b7q8A $?CaTPNVXj8R"#kE.22A`Ch#,stA^Or8i02;<qm+kF!Cm16 V'Or& )KQ-L.o>^h$6rX>,2t#^r$6Ai)Z8q^=8tr]BdP!WAb*5=[J]Fl $c#Q*JPX\^PnSB8BBSZQ2aTH5qT;:\$en7K737i'C.14gE\/ FK$.`6Ps>k@6+l0G^7fAmgEb\siM4rVF?]2X=Y'(4]O)jBFdVQ#ER0=.BZ,scQ \;l`>Sc3Sej^,YRk+ka%l,eRoANq5+E*$=edWYdJo<#j,8]YIK+t/&6<5.WW2& 6J$i4l[gj.^R&KtPq:+\:AR:cpX4M30_fl77Q*j 196-t9i>PfNLh$/#&+-:tIq__jbj@fj@:.>e?Ysd?=WF`Nf:mSM.0he25-Gbb3s<&#9&Df :$OJ9X%gMm"=`p,(otl8II&M(kn$3M!UI(M\Y'/Cmrl$@AE9 _;cip2JS_e4plaNP)S(9;76Mj]deeSaT.[2b+ZJ1A<<n,>oh_/t!XWI\Ac0#@_m^aT6Ng@0Vl3AscN,ib65]4QoCLg58d)g<O87SsN_-eUS6#nccYZrI<K<P-+QX>dO<?&k?M@JspW8GM2hG=Tg2q83k@ld'+:#(pfRr#09qc3Ue&!PWg9"hYb^>(&&qJQ=J!T^2;9)d+0WXp@E9/n188"eMrV4`Dt06]dY`pX;hE)!PlT(CAa+.MNF3C@CCG<71rkh;PN]Co0VcY%biWbOt]tLB"__IU:L 0? 'CS5ZlWbAlG#$"Y[7rZs=4UiCPKiHQO[ai`Ocl-/R@a?FSFaEJ>%>:qhrPK7O!qS;#EI\,Z(A.nl>r:LY2N47la4e]obrh@0k->>sTFQ6L6T*$AKBJ43DHNtij?HMh r#d.WLOCC"@LPX`-_q1Y3bUHA0<\K^k0nS0O,?f[lM'Y(tBM$2A4Hq-F!3X+,X\"MH?M/6G *NTRg\T[ol5"V+(T@tf=a5'g1(iDWr?9b^D12@6PX1a!C3B.M%PmMNXI:1k9NegL(#9D,T]c;ZhqWj;:[CVs-nflL+A\:7L:1Wk=1e+%4`J9go(4ap9h(trBJaP+3!]LJA-e-lWMp42AfV",>7<S;04qKHDNAFrk3<ATKbfBdKr.;(X/UFa]<h%-"IK!t55i369VY_f?@=#">(5$M58/_UAs'9m$:,J@Uc8jefpVg@PNXiF/b^bV+],1];Um31DAqk"nE"OR)VR/^nN `giO%X 2ZX/S`&rr5\6Wo7ZN3^!SN'nq+P!$7S]H`.(&gAs!?V[6:GptG1Z(Der*Rb]1^D--jX(gPGZ4Le<C&.N2/no<TT"lV9O`*WfRq%oBJ2dKVhHq"f$tPUCI0;BYZJiK"^A^KW,D]^3Z:Af&+6L1A43J%I0YCkAZ^7Tf1Z<[H/?4o7eWFCKEX8n(/FHTpPg]%D,]T%d=rD\9-$sY\O[qKGVL]^A-VVD(__5%t<H.6mlHXGX;!jg<#/p!_bLmP[dV%Rh\ha(US> ZMP*IcX_A^rOeOC$To5YKg"%r/+-%h%iQ>^0Xl$\dX@I` ]T2h$kFhcQsb/VjV<rF]D$!-Q9BWfQt6V<R4V;2B?$LC4?G#[YS3rt)0IdT7*]b/Y6;)pCD,r!lMFcnng_+hVMtjD_VURmL3=jh1C=[<U+Oo!^U"'PO;f)spBB(@tgi4fSQl.%]*pM-^5F.ddTN(*nS<9G1(=mr^b'b0Zh+B*IDW#SF;NS;#F'q/FDV2^qsA1cWZA< bVr?s2Q4@=0!,XXt%/Q>&g s^O,."(KI4h+ARfselg[`Z;WIeV=A1c-jfNF$s6$/3\ek;Jb PHk-X9WpV/"JMT1r4/iV%]"UDg7%f/k#N\!ioc2M;CN1:4!@+XY4d`K*&/Cdjh)KO5@YDm?8l3*2 cnSV2KYg+-S,?NEAF'7o8gE]iVnYNXG9mPb]g [j]1(>!(l1]j5`7E)D.th\X 8?G/dOP.)@)GRSn(EW,,<<E; ]p^+6%sP%jFm8W(aiPTNnPhT%YAfEk_dkTYt<Y9 CdY2%+HA1+3A,G;A8UmPYDa8A74.'=t&B4ns]lo6[g#[UnH9#phl!^;(ClNtRppFs)f7B+@IoNNNSLpj)";cNF"liZp5^gch6#9:03,:"BMC/bJD6LJVho,.^Blr0l$#]#oA0f!-8;?iK0ngCPdtjc8RDUfa9Ql'CC-O>JAl,,"PthC@,<H=2#t@1G$5*.'#0f1m@+M R7/Vii`sIJs+7gp%f#;*I'ZgW7$.^-J1^L/a+P C1E66fA;CAZCoSaR$%q>(Ttl3]S+2e&%>.j:)0#[1*kD$]!+[SA8T@jt/^iA,AE@YQ*a/[BPH+HQ5 FSG*S:,BiW@H_MdBK76.<-k75-AR.;6"PD(%0INhS7ePls57q;J1`.aK-E<pjdAsd'[noGf\N5*gd`Q58n`VddhUJ8!B!AlK3_aT)[=Q9O@Z-c#scjPlR0sN.A_HL-YZR]8O#SigH"f#`mdFR(je> 7_W.mK"[VZlAEPkb7kI45ibQA5LonVs7Ds2_!&;r%G"(!o'FPDT)NAbg/.R7FR[ll.f]#!1eC<@YqiCf1q9YsRA5@`^%EfYcdCjA!Y,6 IK=VOm&sLmA1kkC6eC!*0&e+L"^)pdKQgXAaXk3$mnG(43KDI$Y-pD+h>oC9F`RITFR!D'oX)=OE^eO1IOQ>%Q[5QY9O#ETf!\dc;Z85KXhpALN#4g*.Y q`O5I#XUh*AUb]`<b2#)%OP:Le*<>R-+TP[@Y+bm6n,N?5`#-hoDn']>A[]Ar?[r6tAA*1;9q/EVV<3*>Br_)kk#n2HP9j.8#c+B8\38($=M+';<6e4SL4"1Nd&.O4eVkT@;8;fMXBrj%bWCr[Qcj110"pWRck<pJL9V5\0<b;Etke6AJ5/SR"jpL*=bY/%>p^>qnB.X*cm`S27'f]\0 "l";j(Ah.CA +$R%%6.lk3BPTK;T'aKeY28eQg;2%:bi;5EjP^PlDUZEDQ9 Y%s/'AO?s&+4=&ddn24D&0Z$D>%W#[>&-nAgX;78`-5hj?^GktMm%W=,>KjVV3/a;ik.[@=BoF\+fHtBd3Vc'Rrpm&+PN+sR31AAj@kf*mp[IieK9OqS\=1NgFG5d?/G4`Da&k#!dr3n7jM[NQC>jk8g!5Ie__3"7)/Brqmk1tFUhXKi&q5[9UPdt];$tiMWa'l8mNDZ?Z(SDUH\7N4$F5Wejo]_^J7AngphnD)O7Kk:$;jKVE1\aCRL5aJDW%agA*les"Vk3$0pq?dLfi#2*'S97(Zg5PW*?8m5rjkA<p';]m\r'^[8P-M\Wjrc04Uck&&d'Vh2jDmR$=dj)Ej%8";TE!an2FdC$98F:;kW[(:e)#DFcYkVY*I[jkCH8T$D#%X<V05;C'O_$e3k3 n1m.b!P@3sj0@s19?GA\)b?6&WYl!P,lT7%#)L59:&+J!TO#;qR^rS P^U!+oo+,:%NYRMs<9siUDXP16Ao[Xa^.47@JbkaqD,"G8@_t=ZkerqEj(d(`dhR)<<b3`C*%dGF>hhjd9hk(AS\mB(K?i#AYS)?P[9(bj:jEG' 272%!"*r;tD>"X$/i0A?NJfp`n?dIA9>nb\1TOhZ:2@l1Td?M>H#Q*)>1$@nb[7XhGZKln*7K%,Jb@i4Xl#,_sURb_Q=eU1P<O4 <L9QihGJkr!A%#.p0`Ig$Apq;70+b_*J!g\W5!K"?$A//Ac@=a$9q']]K)C`hBM31TPjC+@Bam,FGfdY0B"'q3h;V<"-gOUb!?W^i@?Y#C/7#r_ts<CDIU6h0%?K\&JTH\9SktiY(S0`.fD770j=gWA)_PH+dP?f!-\I"e$1NORSbe/9:7<M@,?$&_aQe07 )<g\Z"J3EU,L#sU0sa?k3ICK.%Mf2%-*PVR96[1]m#O4"Ra`BAk(H&bVn9CZCs4:8>()+Xo_N&ON(koKO45`8 3pH_-30HH@K3bSIi7U<s&l6oR8C4q7'rHg%;U.ZKOW1BrV8<4)t?1*d:A1Kdn7Rd'i)0YdC(r3ASmaXL-g0 LN $0GfmtP'9XcV2cDU[1BCIE*YA2^d6qVgbWrdgDf[nYbTqo!%&NTrJ37W?G9pR(c_7IPp2E^bY&D3BW2!&Q3Q@BiAB=`;"?0$n GMNEJ==d %e8A([J?LEV Slri:<O@k^]%'6l qeQBd`pkYcXQP&AaAi@#K3XfEKkPmQ]6(Ism':eJ\A3(8Bic+.Zk>W*9/%F'SE7I?]<0rmcA43mj*O#s-U$ZeU;pTV[lYbr]$O11l;_(*.D/A-H9)*XrX;7'c[XNmXb+YIgk9[hQHlU]_t'k&V.;qh9+N %A:A*VSRQ\:VL9 I4L.ofoGWqA\90>\-IASNB= 8?W7Ef#hT$<NoV;aAi4Q"I9@9_VQpiDB%mH<_M8b))A32#_dBWr\4b,[ZBDbA-iOs[(pEtAXCOM)08#9,1&EWmbf"Y1((#hq*`+Ir:UnX,[mhU"nAWSo-k6_s?$,6*:Q&&[1#4=O;RKABmH3W2\jT@mONSAob# 6TRUk9E3Ln_&_jeerEMUIr+LoO/$>s-#@rZH2\ESG2tgon`oM&+9OgEU[T^/B`Kp.lDr(G #r"bOdgjCf?PDPZg.s+5%Gt7lPo"A=L%0cfi`NE)U/&J3^02@-kI\=f0radj/R/4242%X$&pj1`kbhm\F]M2?dnK(T+n'>D75ZC\OI0Ocl0[`2:#: Zd#bWXG[IRSRtj6!r&L/DhcLQ5dl!4n](httJ507Zt)b\=gn2!giP<jo-S!?8p8XM!tbL^)darUS7X$12WI[-,X3ore^TZ`NOM>Z0KiI*c8`dpG^`N -6"dl&L2[%\G/g<?8$'#2j-tW;I2YbAqk.!@#kpSObh*bo2X&&?sk,%f!*bVFjUBUd'$64(_5D"]?tg<#L1R(Ugp#>O<Kng1NAN+2$UNYt"4NY[k&\dPh$H/W=MT83K8F[Krt8-01CP#l7>PPQTp6->6#-SpLM<B37qW,l1&6-RJ)"1Q4:&f@"_:`Gc(KG\=QOsQPeA>^ aqAR#"])_*BgmV!n7:VU%9`j83E$F[K>JBe )I&4hD"DPo)^nML_nKQem!rJDojCaO7hTLZSUFl=^"al.;AiZ#2;j"ICgk!>#E(7p/%Laonf9;qrK!7&+KeKI[`><'8ml`a=<]TBt>!8Tl#(.JAs*i?NWLL>)'sSpV>2qp0FUhOg'm/@8ojW'&pf-\/hYo#-A83*gclkEZ5/3XSRd`Ae\+7d7fN!8GO(e4\qA&4'N pUR]rnlZn&oWCCiG5q1o_"_@3XMb\IWf$Y"b^G%^,rGY.7/1&&mF0<+cf3jW-WbIS ?'-"B6iS.SL,OrS!+"cGX_DQ\V<r\=aaJJ@/4-YL:I'ho /.[V6@POCoDL4e=saZ?_Zeepp$]:F;31n`C,*l85!-17LM,]aZ-nDoi<Mi<5U]A7geSPc>5[6^7bZEeVP`C#W@;XaC^ oK3gF]9iUS<,:J;r1&U)Af(,LV;`ikl(b+0@#YY2s)%`2Mc#ksHWVjk$t2iM[`Z$%t<PbTEZG@kX4e>4iH*!AlRrpVHE5&)/S:sJ[>U)jXMq)4HmT#o0f;Z*@&%-LB([#m3";cEA"jh"_'#Mqn1,q'Lds ZL`b'A2JOoL+5.aH1i5l$H4+ ;*Nhk*gEl(PA^a;ggATU[8!3$C;JLU2ne9)p<$NV&Ma>W"Ak<PtFU7jNFg'Hm5r_o[_ !+Zc=>2rDf28\.($7DnUOGr-n?$K32WYa[Zb^N6%$,I>[>0mN+rn[A#Ph.>M0e@A50.g(%eU-bL\.bSU&imF1^AeY@GC<8qj?Wc"+rls,o%,QLdCk&In%PQnaT<h2S*?31`)"m8=#A2St:h?o'tG VegFB/aFA.hF7i&@bTGmsAl*0tVH`)K8nO%%2IP3Sijs8ZlfUHm\^[_X3V\+OEnd`h$>G_g!)t@O.7Ak!od5-r-9=<$Y?:5MAW\eD(8R4MK:WP?V6P_OUPoYnCW9@#/>DKr%2q5PPP:?)8L#>.n^C#`C*2k=)Y'\?2A!IDVWa"cHij2C(g#ht8S;9<]Hm@.`$]q#0":<k['mLNp!m)(&M:67tG-"DNdfTGrIFqp@( -?<C:l=N*f 7Ag-`/ K%gdq,YM@@L`lIY^6icai*nn<9>;oDCZ^%-o<lS`TDAQkT ]=Sg1M%FMo3DZ5ek/7*la`L27Q$5Ir1q9Kh7lF^PaQGfbg=M24N*];]>fcAQJp8"eGZg61bW^-U&:t0!9N[caoZ>Ib%,2$.:$;o61TtgB$mUmT:m/K^k/sX\R9[5=fk;#E9+NfC,Q;R3LoOgoDW02QOIOQ`M/TZWXX%7\dLI&fk\n2-;A0>3Ua>+&BpV&LeF8_?QUk7er `+MKIMqT7hh5H%Y'!2ahrI!-XC!aDWd gbdb-a7+"+&<$\s54nDJ`k8n"A(SP19r$mM1ArGA\mD&8UK#o0S(@4ph^[IX]@I"Jgr[gse66b5[AEG@Fa61jSLcCk,F7sF+e%\UV[_0`l)S$a<2WGsA2C+dg8lec]'^3l89Dcj8@C#$Il88b'H99feK%a/Ee>Q)%rOWf3kbth,3V??N$H,J>$lPUiA/gD+#!cJ=a4]ae!aD&.fL0e</@,'c)S+g.sIc TlJbQ\ktIi0EJ[i;qN49b-:%cN2EE 7DrpVO ^ (J(\a,=;ZN?E?V98s/^ik'Xb=E<jQh=&o(?JTHsHJ=X>67s+g_?D*&aU=P.n;4EM]Y/8f4qPVAA^7ML>7IA&>*T =LP:VB"Q$m_q7U[X5!@4Y!pe(UF.Z#YU"K[[2GA5N:a7f%B]N$$OPD_(t@MD3<s$]A"8K<1ff]MZsD(e1`'A0S?[/eK;"(.j9c<09/58p$5YbeP_LS:1'K5K\Is(9jT/;.3"NtA^"WG>r_UEa#*E=Y%f(@GAt<A[/^.K]qDLA0$a#Bdj>qfV@d\:0]ZN;B?JG;-C*0(-OcqnDQT?AS1Zf[Uk4s\>`08cJ?h:*,$Yp$#M'A^jq'DfmVA=QJqbo''r<&f:&`*+I6m/,`Lie:5lgK1S+e',SAUZ0>2LOB;_%H?/?Mt`MlQQ.5<q&Gb_i:e7#ITqAL[8nZ.?,^!+Ofp78J:rA'\`iPf0-ZH2L3k=aiGI[cQ.8QeZ_oW;+WRsNEPM5P@d]k2R&+2*pM9-8&IHDogZT@T6)#*./ZcO*J0TsD%/Q%C"ccToIk#qcn?'Mq#ef?@ZAs\6$"](_7Y>[ga>tPdD]&&a\8Al-Yn5B]QNaN!dkJ*<LIpUE/DE.mdb>!`Rr-;%WZ5V_FgbX$"AMbL&CSYRhS*_WA0qZGn8UYIil:!.[7XsdcNLYm!=@kfg\onU)FT^[(GmW6@lm7=2rGD3.FO2b]+b'l+VAo.]c/sHE%LKr;l@+A9,BP&p##seO-I"RUJ-d4]fhX'4B.LAI+,eclYrVadm#aeQF00\^MU3R4eUj-hr)jTX-F(SZ3AI@=k8bkn"]>&.(Ce"fT\50#OAk`RedN!JqpGEaG)Dr@a*<]3`.#k/56P;lZoeQqt%olh:,_O"37pZX[B$Af`>r/&DL@B\1tso-;2.frdR/[@Aql@D95JQP0+jc#FsrA!814#c!ON2<$bjejUOZ*9FO\=4k_[[oG1L)GVVE.:4)P'^r(JHkV5HAj+`Z2,AHjJmnhRLK$=<;=]V^EV-J@4XHc=>@tYL<<Gpkc`dpZ\m@$N\>d6 XEC.sm(lp0UAp;2 ,OZjbJmC4TWLA#5,Q4$[.[-nXI_/Mk=0RZR5Y*?`4,267N`Ja'a)9CA:p67de'Va4ZTs5*:_g>P<C^Gj`>(^gn<sm `-(4Y>8T;ELls#Y0qZn%%KZ?"4EYX8Q&>cl1]5` V/rMX1?PcbEN=+mf?_mOgpAEB;MQSk^\1(J])oAdGL,F'KB5iR'(:#i<&f[r-9Md\E(#2h%Cg^_:6ISQ+(Hk;fa7A(60^Mp2(Fl7`^283p."Y.bd3CMbK,b#/sXc6Oh:pKC;VS(UI<2T9A%t[*T8V'_AJ)m/P- #+1i#90\;(!)e<3j$pL2L"#oi^9L@)j,^>si;LXOB3p;tW1UHlHo)&GEQMN]_A^DN2=$;M3q7%\\=0V0?FGd269qJSih>/acd9njGn-Q-Y:n%>For#\7'o@Df0Be._`)j[#ah"PD:-+&k0,onnBgH;U.qN6/jVT(.U5Rp),hC7$_b]rT1<d3r%W"L8!M.3=`52(1D<lm#THjK#3Q&&WP E=Rbm?_K:X['$[*elP))Z-(CJ\^*s\UN9J:e=6'<7bmi;RSR3.M^4q, f-@"1hTG9N4UEoBWO` =q-4"Ahn?].lsqEF7ssC?kgR!H2\HDg(-%mD_p,:+M$SB7]ko hKq9@8#8S?A+pImPY-T](-HPG+Z?^JV1_!:P\3@[@!tP/[4O*M<A)^HAsNG(L^gSScOm0)2=;$8l3q<Cn]*?oWj V[P$sp_Cb`7*OUO0[A&7;1R&]^?alSdS'A+jMhc(cVX$dS=c7  $#9N(qV8Tm?fDsbsr+3WdRfW,A.%bSKE+AV%@eAIG* [3os5V'-1(BNj-Cq;5%*QVOGRV;nnV%Dls_*W[@AXs[AUbUWXVSrjTATH0UiTQ/;?(H>tP-X%`dSHZgI*1p8@eXK^DdYgWOt59-DED+56A))BU]mU:n.>E"-b;caM=YaZA=VB.k4EQU9qH@5R-K<!k6qT"V\j9SeiEY#"bBoA;HIUof: B%ACMn&fPsCpBhqa68)6>>eimVRI&,)q(F:AaE^4gGOjb4XtUpotYh7:DCk<`G,d8\WDn@pnDW=%j6"#PU[&?1*9R 1nINUf&LE5*tk]L=q(`+Pp'A^QFg"Ff,!UpgX?9_FhQN9 WGn%"6/TXB0i=@P.]qGlBhG-TV.Y,&/gU7AG2#t6+ZDM<Hf?r4/`#5<ZgIT!\ .Il3J7t3`6fI>hM9U]EaeVqRm'0@aA!_4XWM3-i=4X7I>*e#4)N@Am"8O)!YZT??m@,\CS3g$3!2_V)SoXh3ptCNXA'BS?a+Icp$S0Fp,+:rO%TP;KW'f2Lh3ap0ngKVc[JIMRsXf LT#n>6G39k9dj,4V89ccR<&bCnr$Jft*ALJ+Kd>,E<P3s:/#)VbqbsMO6`hT4J._f[g-t;"<Plq72]cA"JSAKKAAR,\.JWQ[a$(@Is[`f*rjasif` Z]1.U B<YfQQITJ8:-Ai\P>m4p940ItR[1Lg,A:(WA$d.Z)PrBJiTPn;kB>7(/=D[Wee5:T;n:2CfWM`"T#nW2X+_09\pr;KR0j]R;s)9F>k[oK;c&.'J<%,Atfb4a+8?#U%M7RpAT$7:!ir$YDY2$5lL,Gk>#JSbEA,ZgeQ[BEg""FFc.)5Gdm17UAV1@?E'No2ETDfp!(@>0=.Bf/o% lS(b[:Ji4-9RRiQD8IT.!bVtCSh\c\Rs7147GpTR*0g"o`D6 3;iHc\Qh8ojSW9*Tg'.RU@3]ai]O3Dsj-a@_0TZ_9Q?*<EcLfr>poA90%<S?Vqb!b9I'AFo6hH?Ic2WN-f,hV)KAUEUG HA8+cPIACA/\&^e<F.'MPD9h(tSIX9T.%Ps@#k9/<j^`CXnODO7/V/CFAmh-_cert^['gVC7C<U#dE!+q>g3mkH+->"sD,^TWp;W`-3pP??NI%QjO?lVqq3-h(.W Pm`/[`3F.'4.6/:@%b4lqtnL\86s8@QLZ\On14Op:jRkH0q52s..Pk,<0%gq"2%jdS>(RAVi:=7N?deR`1G"N9D 0`c] 30^+mBmYHW(,o<rC[\btn^G*1+rgqP0r&hVWVj_RotXB0l`a=o,\/k!?]\sDV0Y\.`rTL.!E4UkWbVV,V3V/oO?MA;4-ttr?$_26m23.e*-l`TTSX`IQFbWS2\0^Zpr0NbO fs/p?V80c)_!GKkp=rKAsInNm;Ajr(C/Y@CIAQ"$g*Q1gs#<JjIn@N?QA15Y]'+^L'hX$Bk*(.[nA[:jG?`Ah<S)Z,Fgh18cU'e?E]E$V@hIT1]Kg,%!1j"l %("<b>/:*g,VfP/?t`[:i<F@RRZGC3:4$ir*2%$o,g2A@+&NcZN8#OSIFiF%\Mt!EZ'4!e9;i(_'F7A:LaA&*GGgBLK"g\h4:(3',dCkR\"AZ5Oqt_m6n,N5N<!?gJOW[fZZ6c:iJrh\%ir"P2+7n4[sMqZ*EA^YHgTpA=ZsA!B1o7&5XqG\jSMU+i>1pd]g___+t6IH=JNUI>e8SCpa:g;OR:eECAj`6'8nlo@s53e\WB8j*DF4C) Jd`K#IPBX?#N2@#8OK*EjZT oMhTfLjt_TqAno*3`1T'.d/ R.kffa6E9i @=3k=F&h/D/n5Z,c tZ63f$=ma!%BOq]1%n's^k'ZmsGE4*:Q@7/JTY]iA&\KU1q<$bk9N9j06e]F&m\207TRX[4%d4g!<pb_heJo/Ln]Bf64Zoq\WhIRR3&,c>3,sU`cXAY9$de]E@Q!C%q8P281s_d7d(bpA.*`1in,f^pnIElntTT`1kJop*<<2^r?G5Y1dP5BBYQZ!btf3G#1oP'EY%N+'MU2q82,SQo6j,oU?.D9? rZIdf_AB(VUO!M*_7$,5QTTX@(AY7IcNcT>-U\r!$.rRF2!d$=MBkBQ*(A`Om5)LJ:. 1*c6YAI/f4o&%OCp33UWk ,#k15.:I!@]mT^-<;'_ANt)H0)!FSjpBV;7[;I1/D">_4.!p3V\CL=@sl<S=jk-Wf/jN$:fqip63UnU"d(9Ao-OY8_oX]C OY8_HdX"%8SXj?_/r$"<c:Z+4_-(A'%P JYq`\71]Uf9U>elia8UIF Ra]t^X=mFrQH.Z,kVnk`iFl?mB^;aL,6DA_HZ6A9(9n0sZ<!2/@j</'4+bH$/17)ADmR9e+Ogf5>T#d1GRR;tkP>a(q)[`!!Q9,OOd*Ua[>\5kXh,0Qa^j`Qn_Dc,&A\BF Z\]7M77#*e<X[tbhG&Zc\*j*O,ETQ<=$P_qL)ssU6k^mf])>'a>HGXk"=rbL4gF:E5cQFIS.0PWfh^/cMi4DZtk3;f;:]-QKmP##oD>`;KilN>6f&\?Yd-QmLoZs*7[A&UE1h*KCl02W)R#/c>>E!8TiNCY[NLh_aXo M_.7E9g9o]PCS`/)Vs4P9;fXR'3!XTO8*"LI37$RbVf8qYC]Dqp%BdUNX]RO;=OGd:\icQ)i )XP#,C3( 6_S9ksX7Ar[760bhT/R:r`Y-.\cr,Q1A9/38#YJe%L!rlC4mO;KCPMm2@p>C aQe(;9LdA.M .N\*A3,Xkk3p>HU,'f>J(m+&eRi`,.10dWkf#rJUAW!Mf$-6O""@g f1[Sm@@]d[nmR#hENkFb_J^QQBo@g+@2:e0Z2A:^^C5io&\?;+nC#RYC?-I*e[Pk3iA^\P]AB'q5)_ _C0h7r^mbr(VpO^>?0K(ATS5Rah[k j%@Z`[!Nb J3jAkf_S(\>jb-bYke>_@]4A#QW(M='_pm3FVqkBG1Yem83gB!E\XfR*!19aXN.P&@`V$b^+6PV/Ql1@Z(>`dhXh48@JClL=aFea=?dfo?V532QCAKYXbUlg8;_Ubm,!j+OSg?MJEMMX/M%[(\WdK :)ibP?LHj5)ai.pRQ"dt<=mA#E-`t7C5]DOVN!!mlLfC\\9&oj%AX]@1M"BB*bm\ >L.sAJpoI]m"IOMoRRmgD,Rh/k>_KT.m"8``%f`:2\bn1]!!B9Me5\@,?8]59]rrR>GeEJi$knYBNcJ7Ht4&TWEg-[end5AZi>8"WI!LEFTjp#e&jOIJtQh'%c^g14TmCH ^"`A1]Y*JU1JU>TU<#Lb4)lVVo1Lf%mJkS.g>VD1MTjo)-P&g^iL5YI8Li,n_!;3F3/e.\I<@;C3E"BIW:X\<%ULnr#W33Zq]KRYjGXCoU\mK!l.B7 7,/!_XK/jQ4qebJ/F9jh8IU.8hJ8V>]B$6_8NFc-bWtA`f.f,66;1o"QkD`1<# 2@HcgshmE,p&cm!Q_n'oWB'RlMl<9"DBtC;"D[P1:b^8gc!%-e(=?T2'_ZoiqWiA9&:57Y"PXrTU_'!UAfYA]H21M(lR57/e=AO'9SEUFG 5_^"^k>IhTkL<7Gq/gaFldm\F=.* (PA;n,QE/q@N9^$Vsedg+ar<k2=p?Yn$3?(eFU[m 8s<?M*!nd;J0%"ga21O<',U3GrDI1kJ#a8N-ZWA/iRTP_Z*Y/LseOL 3*D[*VD0nXSIE$]\5XYJg+(ne#MQCtZ":0f.ItlfdjR("0C+I0taUhc`J_)TmYNeQmLI_/Y1+ RI9^SJXr>;;&AK\V'!7>1#:_E??M\l",@4da:][-dr!I6.'lrarP!TA06=8*k-Am%osAr;G]9MdLjSj1>ThQ^Q.8JGN-YT;3=C*a9>#[B5NnablrMirPbjlD65!$Of:@[I25EWGM[X \nsIXF=qc`Z-\]^Vq2kSX=G;$5@LQ1>9_4*"4Vi"QmAkDm_ST*7;drHQ3if`J7ng5ne`%8aL4,f:Q5GS`LRcp7Z(4XVd^Iko=$]@V/ta'o -9hdlF@Tn]%86a p$R7Z.7bWcpgT,87=ZQHX:KN"6a^*0A/ibL"U%:E$&= )bjRo.+g`%JtkiVXN(o 52Q]K,XJ8JLf=<pleKW4i9AF f^r"=he!\rB$#,e.[o@OU(=sW@&fZ_gUE0grrg"g'QlF;AlTt72Z-8.[O-"n7Z9L0=L>T=$'B1;JI^5*Al'A$$!*PB/%b/5s[M=77C3BWb?Y\hb<f,/#aZo5 76G/NqTr0Y4N".E#0]j1nZrqUYd@Kf!Yf,/^(gf5a_4eaaMoZ9>$ceQ[pm+\:IL`Zc1MT3\a_o_T5603tl?dg?pr6&\8QkeVih6QD%-3,oT!$bc1[+] 2I"dh+QA1j<DM>rB>79Ud78"mnif$jMJ5qH>lr`ck 6[fmh?%2%9F8eCPJ/T7<0P%kP DFG!V4.N9IG"&-T%p,5PLA6PTA5`_6Ibc4lb9)#eLH("Q<AbHMkX+XiMH:`k[s eaAYjPD)Em(>=jOq),ZD$.'55&rl;`54' ]&%5W0HV[_/=WQs7b3>7[I $j;SDo&!c-=P<rOW?^dIr!aI#&e[b(&UNV_?NsZ?/<b$ 5(EHQb@S-M[&\"DHhoL3-_=@=UX'fiS5FXF:8!oK;+R\9NbB'=SQ`QIKrG9RG.oMXcrrtQ-AWbYr"I"GB50NN+sQ7S@E^TZ&RIL+^B4)+q2LQ&bDa//(DQ@Mg0+gRcZ1'Qh[Qq0N 5* B'rA!!NFdpJ'26Xo)5"<2dNRK5?R(FnD\o7iOrHk)i>@cQ].GPN3D7coM=Q!#SZP09*d,7:WjsF9[6<k!N-/?QAfK<&.1$<-dO30G6tV_h5T(45a"Hgbse"TXr:W1XDcnUp"f*R],61TVIHW+0L$YUS[h1A=c".(D:^eM@^\&UI30.aURP?P<Li.lo7r>72(17NmiVi)LGWON0BU\45;oaHcUOhhrT;T17Qcg6O@H(#4r`C65*<D1b)C(+d[Zfqqgj!aRoOtLHJ.7Y1fi0:Q1+:R:Q&5;IL_X.D;=-MrKQV>m0R4Z1WpeM:nEjHZ)sennKseA;)h@)a0f1@91A:r8Re_p[CJ9[o8f>^2kLA=3"kN4Kc0al_W+MeIk"MhrUT>X":0tOfo"U[A?h"AWa8Hd9Cn_>ULQY"fj>[:]EBAQB-9YW4\nbKj:aNm9(Dpbc[jiVb".Y,A^,F@".G=iF6"$G R0[;L547[.g(A+<TZ>I`+8!]d=$4IY< .b4K3&+0-H7eWgKL^34^bQ]*I:eC%qFtmrF11[jIQo-QPG>_XTraYIT#+T#bc]D,Y[nf7-l.d9JO%jq+=Zd91c]3/N%r-H=A)T;SMRde\KaV`lXS184CL.7LW4S+<^*2hA`PBFIUVXm3Ngfn;jCjt+VCOF(04T()pTfY*n]S^c0"!O5<Am+_b)*8*p[QDj:;/d+WeQYf^5b3^$CnK5MFBV'Q00JlLm_>d-6F/M9d.p+V1_AMJS>1(PWBZXG`hQCQ1]\7MS'im!Y$N\B%cJ<FqbtdAeO_IB4'L93HlPi[64thO$[e<'/Ci75^Zm)a*pU*!.JA #KGFL"P1K&b3E^ &Z8%((FRhS'g.SHL2CLGg<2C=`tjRO_bKolI%YlbF+:ekp54:pm5'e=:9nV0H"tSEd$$\2If[mbLfRM]GATD02`OG)KL,j=d[-!W+$.S$:"K@SVSZ i_TbXQb XrW+F8'Ph2@6GV=)%n5-q#1_$O+3q)gnp*h[SMVlJRI_@JQW_LV/oX;CEl>*("f^Qn-XHj)$ehjA?TmM!rLA7c9N**Oq> DK5Rm@[jes$PclOsE9EmDG:)5[0Ct`5_,Y/,/dbc\:ZG4K&0DbM.<]d`YWcPqbnQFYb]cC#\JL:^n\'s6A^GJVA*.8.k)Q##HI<lWWI:^9.cB:sKO,i?eIA<a488a2,;a"k 6brjjLXNb*24pC,5aoYKr*gN %6O)I"?IW(20FZWD1+1c4P-EnBWtqg6\X-*Id27"rLY5bU.q*sQCl2S':r0G#?bL?;9F*i-]/O]^$qS5H[SXpD?XFTK#0BM?\+-M)#YL 0&<8O!!lblA;r*`V[hEBRO%pb[#5;V=E,ZSa4D@lKdq^R2`>+&P*AldtSe%O=5V-U+`&SDbB8iKa4"'1MA7*>/BA&m=W%U5"U!$M]l+mm93_Bs.&%VqA9%>UL'?l1CH'\#5D';<D;V>FF?ia-pi2A$P=Eq+R[$\3c&%![H60R^2+/Dq8m6^rk.0`YeU.X@2LM_j-.ZN%An&EHGc4qO5/ZqXLU4OgKnr0AH8YDn*Q"o&YQhsEY'^KI&d@sCZqq%#UE?tNA,9_E8laO%Se\R8LW?HA:JA&qsFB2_HI]k?'4$-@-GrNisQ>$gaAALde9n?Qt+&L%1R)4)^Tar\fW(Z9f@%D,=K).sVO^W"WVP[X/-M.aN'.hQfO,N 7o"2`5Qfg3RLhkNjW#,qWaM@:\_=OGg]fSKrh=[\B=9C(t>DDr(geZF_l`,'&"*Ifp?N)cmT,6bOTRCr=A6,s]1sB3n,5PpRDC@m,,'jEo&:=@%Mdg:<^p=d:`8a<_D=bD`f/,([?%n2e\YK]"D*5Zc@\`3lnF5jLjKcG'A4RJI>J#(':t<rG9Z%&_FF[fj'q>LlO\$/L=/>\0^B&W+RG.iIhaJ8rJH5 sI9-$*o=@LKY0@c\8oVO9_OZK]eDqm]7!9";e9iTo0^XZb<DD2)MAAR#d=%sk*7JJTGMZOWK3PFa=e\=>% 8gIpesVHaLrgR?`B\!40b:@j'Io>8&$fKts7%c\>8WkhB$/@It$:oAlR40A2&b(4"/d5+/'-k  H4f=2UZi/QWjF QBX<"/ Cfa7:JNN&<E4a-`b=;^^G\'BTG8R)oCOc_@H,IIG<&3hMr'*(<a.&DhY5U(Qi&j[D]>qPeg<QN/o,!FJW@-0ZHG>5?cBiMK$l>D;mCQSJC? dYN:Q8rhGa4&9A>dtLGUkiYA<Bj=(/(h=O7_`E@'/e[RTZ:U-)fK55@JRo@4?M_]L*Z9^D(SZt>L(N5C-/,NE;^lq#%c-GWh[A+f;20+i*BZ:+9=BrO),&(L`N^s!@e:WDD#fWY8i_^dYReFT4? _"9hh>)k,oE["p-)2b_j:)o$TRU3_4X@Tf-E2`1$&i[Ar)*s'-AZdQU9V(^_mW0sT1V*/W[m75A(_4jOjRAc+\Y9i%fH7$4DoZNO3r#^=`s;6(1-Hf#\'@&R-TGYKTNG-gn&"(jWpA_,a2`tFkM=aAPAt7)Xh\]g9P&S*qiO=+b&*Wh`OL[(g3CU3!d@."+<%?DN#5^YXg,^b+%b=@sA'-i"TZc6l0flWAGJF#pL':>)`_(baUeiis+5q4"s!VaH+X4I@e_8>^OnTMMEaJ7Aa4SY42kjoR _d66kF6iHA%eK&s',ib[G:>2 70/dLeZJhlsLba%R+9f1/XosAdmAZWbC[\g#_c.cJ0VA6gAB:o(`2>O*$NO_E7^1Eh!in[dM!Y8r>j@dtFcqZ"la>,d]49+e!Tf_J&A[QUCr,c;?HO%ji7g_9J)$6kd)ai-P[^C?Wm)M^ <ppHKsrS$D$.?WGiUH&<NlZ6^t75]Y- L\Cd)hC2/(<Z& NNN59)=<WT;l_%`?QUB+8G='%^S/l]C[pgUhQ-<a("G@iTE>\K,RVU1)iZP9lmC2(Hod:#@$9cj6+-X3r)Sr9`97JWA::m;rl[9J*2XLE#F0U*IB<se$bK3j@5\#fX7I'THa`tV[<0=>$P]+\Fn>[%cWjdk._ <LQP?W^AdkdZh\QNb "-e=hp>tc1"2eWIR9#K9Y^5&%jZ$L,LB_K+19gB:AWdR!g%9?e>W/Emc26++H.\6F<':j#P9_kH_KGT88=4TmVGm[[N_)C5>;O3+>i=1F1UAE# \"J07pp!oq8d..g(((deH1[)^[,= ((s_9p*%(M_^7 l"rJT?l6n:iU*dgfaM r#e-_*+<c3jIh\_$A>ADo%N`>Abj9'"FoLZ#db$&7Y_U^?4*SS>dG;K#O's7lFWA=6qH'rC:0aeXFB<^<pa;6'CeAHj7W\A76A0aHJh%T(R pFQ[9U<3q[f]%Km1lpM[;[)DDp6LE'mBAnm9Z:t*&6Ej;X.->K(DV i%3)I*JAX3NNL jgeG7Q[XHVTa4\2OA@*5B[AIF26I]:,Bla4,I*ecIY.I9Z?8*)k`=#]88N;rHN\R_9414grVceT'LM[6IF<n Z=r>]qaa;:NHd@W!`EAX-D5Z?gU5?bZ_TLR!l<pFX72/gN^Q69<(tEnoP4DQAh5ga3.7gfqog]bBqj)pVg^QUVM'fU2[`I1nO1BZ!*9>lZkUaiB?iD8cjVZX9B^'(/OVNm0I_<e[SZ5jCM*FdXNgUb=(E46$a\T!U2kETI46J=tbA_l8"sJ\mClg*+]DRC;Wj#NT-Rjb*^I@MMareE/3<Pc77KE<krg]k]*mI+j3rYA2*k7kEc:9CnbZ3BHQJB\N0=o[>0&6NS0OD;;bK;',UX-GlB'gpj-n[fKaEn>sUb05NM^$HNR-<3V((RDpGKA-PdUA]s<)lV@r&7(n$A>M;D`0LM\ekE\Qjd.';qdO7 9KC6g`Y[N`.$1`raN?o;qR'r Vm@_'JF59($l21"`=A[Y%\(GAG\qIf5 )N'C%">WGA,Q>!-#RTW/?XRB:_n)^(RWBA]r^GF$U@A=oI''fAZ+RY;!EOV6E#sr<iH44G+hZ;`hR_Nj.CWM(Ns+_$a $-mrSr5nt;(0Y)fI)S4GEjX=`Y0n$B(q%%cb1 An;1nAi&-3\#Aa3jU!N<Vs846k^W6M<+bALW@3AA"`ZlQi26;LQ4cg`ChhUb"a4C4Mdm:#k4`A#nT 2SC0/( K:#A`pa5P"[(E*L#D[QH0SkNO#iaaC>`!4"^IqAU)[p$Us9q&"WLp:@Pe:Q?cLY(:Q\Hf"-V9?>akg=f$,Dcj&7AM5s-t3`N#Al<:"UVLG+c&,\k>ejl_qK?j6`&Or=Vd"%Np"b7q$8Od1:;*dfnp[^UJ[,6t)YsVkC@aU$>]3S/LKp<#40TGfNP*+8K*NUl!!]piG]O4A5#HQ@mE2<<REeK$Xri?jaA780/G^C7>rXNH"K[jE*5g^(5R9!Pi?L3N[:3AWOUkH@(%kZr7EMbnRn395W/B57o7d*pN`iHQ hWbkC$j%ge:%dT#6LcPK81jRcAd[%s_$c+q>8hO)l.bbY&l%>Z^c6i>\Cr.GY^eU/rq2C"mai_W?,@ JTTS*lHpL.DD.\BBEe<:*W1db#%+*,Ql6?+X=M_nb7%,%lh[Q,['nTHTgdT7j?*ls;GT;;"%7+bnB<s&sgK]pH`(-?$Do @%&&dVVN.*!%bn*2+-3#NJR[W8b-ocF8=EBpE3 TDZh9MN3ogXFA_*oII7D@UeRV5&)L<hT C+9df)-UCicr?SrG\pOq;cqWJ!oGB0o'ai*]Yb&2;6:ra^a^PJ$ 2 4A1&AHPYOlXR%H6oAgigg?&@dYl]i3id>>EK43GV(j"DQQs l<0A,/o (+G71o"@McZ%>0c'Uc.]PXt\>X@kjXWqP,,,V`^l*L&6(d\<*cc4L),GbBo.TmE6/@7OA^/^gA;!pPs`Wjk!RGG2\nG7aa>C\W@o64tKl7SMAX>k&L,0V19b.YK_:P[DGZEPLHX-/`*-n\AO'CjV+&Sr/!>)8r>&diAJN)I0aWj4m=&&&=Q^Wp#pU_-3Y13Q/g#"EQMpBS_1YP&9\ABL6Z6d)f#arHa!Hj?*X+W0:'WWOGV/1All"Qa"Xk\Oc UC><m!$Q QcI>\AqRtCVbD)X<+9pXrR&`"Q<.0-M.Q'c(XYRF0^%>#TN-V1g>Gik I@1.R.4@"HA;hWF@Kh+X4kt$8*&N`;m7UefMH)W6p]ap'J)fQ;)<`BCa@iqjGCDNlQ&-A@^+H)q0CEYsfBs^9+$b!A?ifH`4e`5YcN4WR$q?i;hOgQTJZ%^tZ^3bV>;+FGPDO;Vd^"l,TA/^&.UI-A]979L&'/4bQ&Y==om?pZAVf8;@A(B.FUY4Ao3rcKMJi8&V6pjTW9 1L-$M^@?Xo=Efmp,!#2B0 iT?%d\^Ze<?OLM$=4q,Jd9`,g$-2P%Dl4<\P<p:K8Eb"BP=f;\Pad(f-.<l47oN.`qNYt@'4b`m1TV3qR Q,a/)Aae<tjA(.XNGbL1Kc:V9_64fTk9J&*4pD9sC_AG<m9bAT)oq7D#)f\eq''K8F^iJi?l9674<-\&bVa)WqfHFgkpT'])k*';jIS! 3FJ?+YEJps;5DOl>ej-I+,Etdlo;GeXtq5Ei;N+QHKEa>:p70G6Ah0t$DC[:IgmKiSg7/3hl#Vp0B[;2dKL'SW%pG1PVQ>U_N)0^D[ALc/QTOaA])brkR5&Kk)K8WAUkhpSEj5nB]MLc#(T9Je#LOR$=gn>EdiskF\p `roU>)7C<G$L2gPH`rmc-AE$3=D]UZ@:UQ`q`=sO)18I9L!pDZ&nNoiOftb^1l(KBi9k#Ek`SmF&_d0(@t$Ybj^jnnXCVAOft4TD_s\%K_IcT'C","lpJjjtl7fGG1;J*@]BZUl54j6VFW=+QjTO[1ne*GO@RsX=j4F /^nFZWSPS=VE=RJ[?V$21hQYLS[c<1)jMEQSj3p;s)_?D_+s9I!jokC8[<TOg=b&N+S=[4\@r\%Q^BnB(M&$EA<dhbk;Xb!\14%X[>3Npbd+kW fo)kBat,qpW_YspA_A!fE/7g@YVTODlV?f+9LKMVI mW-7Ueks6oe4AF4]Qe6I6W!J8M+?IGr$&/r@EA,d4-hU$]bU-bAapk6/*_ 9k(1)<,P']K-_?KtcGg>rm/YDhjO!3lpL,t*D4j"Z63)kB1_A17LJ+B?#(?9*:q=X)VQc\pR,o:J7O"gRi#Dk18$\Mr!:"m*_dh9,8g0YIX`Zd0XjB!S+-Pft(n.?'kD%%`K>'",Oi<Ob'@=ppp(9^E:UL6cS(bc"p!:/6.%Fnkbo)gXSBA[WL7MsD^1 dCSt<8'0e&=p!<='NV*M@HI1qKX=C^&qR6_>rcg1L^\+iJE]!QEf$J5l&_nGWLGI8[B:k\qpJV1N3(/'/H<B^'A>RLb3G57Hfn25*[:*\E`^< ,<D "mmD;h>rr/oRh ##dl`7>i5"= K&;;2-8gsF"=(*FkCoFTd=_,7\^R]SKoRlkF8]sLMXG%Y[+im6_^`7fLgk;lC-)BpohMn0?p"6`ebR\'h"%U</1/.7K-Gt'l66?L>qBC:?<a?XG\7>A0-YHU%[^K.=pPMhB2K'q'oYgfnhsdH3:(LTqpV6;'q9pBsQR?X9^6W:F<5IQW#Sih2J=D"( A0CT9W_nKmV2,EH0$JWV*6D\s?!:8`4$)Q_366,!c(ga+Jd;lpk5gIE\k+&f]o"^m-R<TBOjEUfYIBEVMPRsg4Gr(ABa<UcV6^n-+<F%'R tL<YG=;T)D7FaVR^,#jEh^T9!=Ii$TXXst#8on/lmnnq)!"dZ@OtZ,M4rLbfW)t*aiO8D;)X+KT1 tY\j eX5lbP=?'`k<Z-9[eBi"cT" #%P1'&Kt2\E\/LBIX"\eQE8Mj@,9X[D*,9o;A'Lh#A/bHXI PdL?r8FcZAFXJP&iN%'g@Pa?!_%t_P6S'5V[H'TP9_[fFteS^oGc&bQl$H1?%4'S\o^dSABisI(]L7Z?<*1+YIZ*kcB[o2%og!N3BSI,UE)JGAlg;I5@E)G'AOS$Usn-BQ^\\kW-i?:6q%9".p^l2U-H@X78;WnF:dAcY`sO;9rhKlS^?Sp_dC:#H>)A(M#8%rj"NWKf"NcE$%l"!<OGEVKk[ftkdipA]>;&lkQ nB!cpgJ5hBh@Be7go+o8fd= ZelUGrT)o@.,EQ8Z>@=elER?'\DEN'iJrTYV*7&EQXk2kLI`CJDZ^,!dK!U1o1 N=*qq8[>t"sJn9 r].E0b*<rIe4""-Y:W1B%XbmC,n^S6Gb$9a@U+NK?k$3oJF=[-,@>>+S'Y`s;hpAZTDZHX+.DA6^0L;cA=B!12p#P=Nk8V@[7e7"9+YFsD[$F/TKo=>C8K<[,T$JZYs(k+cK?ZXgNtQ/H*9'h9@f%Ih>G%/U]V]VYXE_^o1h=a:lkC4Pb.L^eA4CXn>st4+jakA@NS4O#gD1V?5kOHNC he<B!b#CLtrP0/i !IjY>P&X6<>2UkP5J0Z&J?/[8ZElsB@[TMI^N3-85UZ /mUYZfSjGL]0@si:nj6;9;I)C20)BO?W;F$!G?<Y.:s%e5Ze3=7b8I#TbITfnK8nOrLs;*(GqG8P"HX(67Q&0I?8`DD;N9k<_(r0p#=P:FV^W,#& [H!tVq#g)rbj69M[;_aQiSN%r0.Q]$jAiIU7Eb\PEJK[(:CHjkg!U'>\?b #k`'>t"C-C'+YJ`@#Y 61KEb K?Z)5FsC>IIfH+RpL2>W"Q$JZg/2Bk;%Hs6(#a,_S%9qQ6_\;N_Dh"BGrOGN049+fbDSANG=*P"RoDQk91S'nQCIBeng42;,>&GA**j?edh,:>Aq\]5q)c[$E?('Wd-Z:TC5DS$BO PTUELG`jLS7_N>  bGiU 76%\QC)5FQSdDf\D>T#"^"9J] n/$aA^8n#t$a]<A]&ogN[l`U3P:r$1bTLFn`nJAP!ZD'ic_^6.8r ZYBmH0L[RC&890t]LcXM._c ld2+1ac3NW(nZp#&3AtsBeMFQn+'dd TAW"9.')G#W1>%-fW_j#%fH:JTF0=l3?oHUVZIpJoHlnM:ponE:,;">)l:Hnhg:@bUq's#DbK`L(,MU$,N+% r@@4W?cc[I,_)daC_?T"tSQd9^%`N__pZC:O[gWgdhG'b\^0ltg'O"koJB)J-V!iI3(1fjq7H;BrMlc0Vc"YKo(C/Wco2YTaU?s:<qL$?C905!*OIB,)kc;;\MhlhaP&bTV"o=7aN+$K%pTAT8rbZm#<h6f=O\*ioKh#_^FS?9keEe<[+N7l7]MYl4S\IaRfi_rYb$9s' 7ae%14p@=H)M@`5Wsf3_0Y.99]=1p'e2pC$l[?%-+)EkskqF@9]fj-eq8@,AG=[(/pLj;&2%b9iX=-9-J`s/f3taq*NMTi4P0QX/qCEDesdSTG*U[CC%3KfY%I48km+?$ bQIhReLjnkkKZ-P1bt:N<LCE!=WbbmR$a(P:hT[Fb$+V s9Ze>YE2rF<qqX5a_;M,fb/"PJs=0/iN<VVn$r.KP@A>qB81/df5\W3[#]'0IYYp/8qQ0[_*tN!3KeAI5-4`d'G=&Z)hpqPfLVJUG_>>>-AeHW&9Mmt,l1T^hPoML&N@T[[deLkgBa^pGoh3rE66BW"?%K))Nn2X*=5FA_6^bT2hnC7/H%cMkZ-&MV'0JFf#_HRNV* .@j6eU`&l2"W=R)_EE0h[-,="/m2='J2>KF[Nk['@K_,\%BHY4]P"<A\0k$Et=+=?/RX9rL"*K*q*-NP&pRrD^cGbFUm#@kTA&54^-+796 F0j]DaI/s[Ct9-1C5;?KTQZqaI*LKSB[OAA"@PY6Z5K(`-hLlRZ;5;X;jAOHhUr0@UY=erF$<JD'$NBpTn)25kF@^P+h=@E,K-gtF3r.(R;J:A[=Arfhq,=6d!p=?!b=lMokbLYc\iYOY6#,QB%Y;CVX+%h(7R9Al3+SJ*WNNBLQUhmIK&/?l34gci5GPUh#kF2nXB-P<,*&"O+ar(Fnhd3*A<P!?@!iAJ#fBVo;0RF#g+$N[#]=UO\T%K#r71-#l][9Hn/,%,e-;H++MA@L&[c3Aknh%j7o524%[N,Alt89rOQt``#S3G;Pf$#D"Q9FZlhM&NlA0>STZ@-Aea<&'BE;]t8No8RVf',M@3<Goiioi9QS;]Aph[M!n_YH""+jSSW#kWNL9AGsk';OjV4*'T*_=rfgP^6hobU]QaqlW9I=fjA%H2"fah./D3+'ccO+qXKLhY\!7 5FC';*aeMU;i<si"raA&0>4\/G<3jI`A(T0"@b,Fc0;,AfqSb0=o:a"I*5`'>ep4#4D&nQ6\=Lloe5Qn-ed&$4W.KN"!i03QP9DW+:smc2_$gO*T2MV6;';sd-06W:'ne-fpapE'j1,f2ieqam>mJVD0Km\24 _\ApdeB&@gq4%fJ3oq`.&tiR-(A bYiC([QPaT6].XVe'[Z-6j14_K3is p!1t_l^;?@SMJC;pJ=_6LaUer7ZpDO"@3R:lqT_(ac:bSd!EK*,sD^s8R0]as0lG17)r.(W%lA(q!b=J:E!rM8^dA1?Zk^ab^"c,Zd(@tD8 sM.[E96p.DKRG?Xl)oWB tD)(><V7M$Gc2l:Wj@^UY"jnW6j#)Yrnm)HYTQl\Eb2^$0 n_SYph,Wls_`UP`i)gT3FF(@FB2kIX@;aDOpI8Gr?hEPJTcn@2]7b0hk>REQCj(OlNi(gC]=!1ajYA0AHo[%2cpmW#=YIga?,f1E*W>9Vk(0DS[spBF,]+a8NWn2f3A)kOs$eG;5 *LGGH:3ZDK!B5BZ+bX][I,Jc47T7;#i2Re7tJK&]_N(e;qSY2l#.bU9mebC:8EE"U F+B.-o3GRnEtA%NM]7ICk(+h;KO`I&\LDE. B\VO+0T!-OiiOkh+.]RE3DDda0Mj:L^id\d#PdKc!Qt/W`:m-aH+8*gq\Zd)0HoGG(T:'8LH\Oj0`oJ(YU^_6ZKrjZ*t(S2d!8qMTUn 8Wi38sSCkKcZ"/_5n%fUZ!HRiaMYF'g^EXj93.-=(/oHe'!B,LGG9?cF[?X[WcE5\?=7% ]OQs6nJnRJ/':A6UGZGm7g/Ke%F[7p]Bs"J+>CCigJ(T%bZ"jnPIU@G$(++1S_@b5%mREh&2TbH5II@A,jS.[MH\1-b<"?Ak'6,(CjbRG94=qV%8 TJ6Z6&3(o?hYfKn95Wb=(=m8.IF?JS`Qh*R?@IEp,o7U-J4qZGjLnW aaf[VF(AD>YDU>0@ZreJ0L)(&F)-U$F@j5msJn)t6K-SGr:Td+9$PJ2j-s9EU6\:N'$=7BfT)bcHS)5AeDqbeVO6r@":i09:':jY_-2'ZY5['(PYtgge0LB(n/fK"i6?9]4)C9(;g= G;" AZlZW0t3bPYs^?t$OtdRVn:nV/m[@A"p.%9!p&AP@G&S^)g="qA>AVTb^=6T-HA<b[1/H0gPDPg'B.?A:,pqQhWUplAG?F6U"`3!'As@#Al\"W!1T7$2\PD]eM8:Ce&$=mbjn;#Bfj AJ3^BH?Q5i1@[omAolU/eBD"oAT09s_PRjt]g[%'Q$.p%lW`'g+l7Ae<;n-kc0G77fUln7;Y#YjEL#btB\5^nW9n 48 @a.#Y8/I)f;qn12Sd+]TgM1ktq8ZoPOk@/dOSq@<PLfFPi+FafSXchYLS`XJfj2e,Jc+(krLgg.M?bH,2S?/QSBg66$T)D>J@j+Tc;GU 3pDNba3iS3[$*FE<$UE(pF&@9a>)k&1MOK1MTY#1?df*dn2C>hH$;dK5>1b)=j"CNaV-atWE_"-\'\OPdRk;b1U^eIA4e=7k)U9rDASSEhs;H[*,Vef3PhO@&?,Ri,>BAqmEZ^tm._A#[@[9%jb!G#<EJnaYcX_[%On;EjoiX8O$4Ss_WZbc57 *ZmY"5gr8s"BTan,Y/t%f/8IT_-gAAcHdh#aWPNA`P>ft"Bn?:^0G4-Y`fMSLdelJrVb3:"KDAlPH#@m1!MX#.VDA6ZLIdnF(6Flqgd[GUtN:YDReU`>pUB<P"PV6VVWd)&1Q_ZajmA)+>BQlGhQbC:`b)A]:'AfM86]'K[A1G3[Yb"4oD.V=NhSl3JH)qA7TTW?)`2A[(.i=S0N0%!J1D:#";lcAWp>,#d+7MgM&[8%'>% P* kIrG4,JZh6ArHLiW<30`[U[`n0X":Z57 [N*HgZ$I7otWr54/Ok\NEQTXVZKt8D6,q.R3mp>&_IPAI(%?e!5?A/Qbe@ g5aGG(ni3aQ%8;=R7B4TgE=cNBq+FW\An6k@VSnE<(EC-dYOXi5P[Tii;s=l&'p1UFmJO[#pNbt8/q8Mq:I.Kl7<G+ATp>[5+g8)\XkA7=1"7GT.4kFYob70WpJIM/7`^?rOW"*C\'\[Ot%I@a\dc?'cjQPlh\h5R/M@DqMap%_<SEh2l<RBjZc[og?E2cJ3KjI_GL>lgJ\f!Fn(UQJHGTlr?>6mA,VAb3793AjHbXFg`E"d-kr59p,"q.g1FgFVB?%[V&V2T:?02JO!OEQ8?_GKU!:6^lAL7C;Mb@2b o_s\1j:e]df*LQ79TSjDhM;AOd/9Amf--]#c?4Z4DA*h&/?MH0(=W[H>U,j'AQ5=Z84qS_]io5sdC/Y!)Ro/#1-8eahG<=VGleBq$GtMgJ'iaA&!0>IGh<<beUlCkm;<l_n*Dqgl=]6g/%^DQR8]>Ar[[r(DdF1mRYX(:Ah^8=<_HA:&X:*+ra(p/_Dh_,i)B7 WFq+ZfD1/-rZ#rM-i\)%3a@Ud]n*+<H&>O;b0j3c7:&A,T=<273+Ib2EmD[`=N&`99S8??o&/@qoP?$"H#EL ER[h^aK(iFGP%TAeefT$Eib^ "eH`n!A5\Tl.DjW:'CC!8/rt;Xi`S_Cj$Z=H490!0#9:$A!52\G@WG =]X`K9CI4)gYNKW0]=OP;HJ/%pakp c>":0rPlQsSSUKaEQY2iD/7.]oCP"omV(OO5WnrAI[&&A`EL>R_/"r8.O/6cV Z$JsGlfKOZ:6t!G\[[;\Yjb42^6ROJ[TA=jbf9AG>t9_6pnNXioVqA=2<]-;[t7LX58k`<*K?\p8IQ0At;LEW0+H6+*fd3SaI'$<mmh5JkDm\`3-p2\Xo[?JbcO"Q8ZtmF4UY(A\'hD;>abi7rAfNh/,V!@M^H@_i&]O,^,hNt"(mg!7jji^R\ 5WC=]M[q_[Mb9.nl!"BTOBj&Zkp:0<kG4mm]&>X],&nJ$\]]S1?Ra^#V#X3](Q9qUlM2F<sTP^AAr+3@30*3lm:_'2#>qQefOt`oLUd=2`-ILq'kl';P-$m&dbNq4_Xmcam,pA6ZI^Z&eX3jLk'W0^hf('1^&b:oT=nOhOTQA!oh'^#R>P?3+L:XM@anPUHL8pEW+.d*,t`Q423Ea'3*,\8?[_7i8SQ,Z8-EeA(or+LtA^)r,Qdf!13HT>+l>jp'qK'!5\S+\1R[T(lAWG@*@WXWjiJ(-C,:$Q*g;ZAs$K+Hf3f,l'(.`2+Ltg=LlUj]A)h_.D4AVThb_:o"E,Ac[$r=`6CM WM85D/Sa&]RgDY7Q%1/8AP\-`Lla-5N?aXpkcrB7VV`E!E8ClT8gsmJb'3W`?C9rUF<AJ2d?P^P2,Nn@*_Q1]e5mKAA_r[WH#S/p#t$nf9A$YOS-qc2,qT[,8FnN7';lCZ(8Gd+p*V"Jt)$Q^JX q+O$+@fhHVdDal#5?h0&cI2<pmRW/g$/gePX)WObhkE[S@j>ac[X^gUQ9TDjZ"(jmU54^H*-E?/q?8cIS:dL0@ b]9#DoU)^p5b8X$*I51q^WsA'd%2O*N$0gEfr(ZTj5]CgAC2n@"p0tBEHN1mYX"?InEGR7A0T>VMD`$`9?cmc+SA!/^SHKc6PB@7-/P'NLQ)s%@ (7\Eh$-;DE*hDtr/PG[]J69FRXG2K(MJRMkOrO(Z`KnNC<)o[<;`1hDl#((g:W$CrPUn(FVC =a9A-p&SQ-.Z9I o(1,pIadRJHa3ZLTVh].bH;#MkK<-en/H^=(/"fsg&B*b<lI$;X8AHo]-HB&fP0Bt0MmD1,&Q1&9XU"? d^M.:^e&!t*9KTC++i)p=_=!)"`6Kb_T_F22tg,AW?8Q"E[DAK]%'(58-$+<?(.#__QLLP&+SVEmF@Jkft'"^L`O:a4TT3e!A6F)5g%>OAQE_X[??,*N/ ,7=',iAYKN OnML3[P^e;$Xq/Y-%i@[)P9cim"-8t<=^bh!srU3cB\&^^>O8IjQm5HNC/dnKsYf:Bj0dN_)i26qR\k8k@Q0]_tO[dGBL4Prgl'n@/>Uq32\"I/pFTG&X`QZDM/,O t]LC\nSP'mjQ:'NA=&ln^;D\nlQL&M;kAniTD](c28,8,18:6!M7n$&RVZce8TeHW#o\G^F%2_XM-/U5UZ9q4lg"St_'MSKisb"#e#NfZ,Ce(=nU] h/$U.Spq*hc+e[@1ZC^=2J\P3bp8$c58j3_O:0k6WC##3=jW!& .f!B,H^\e0S;adAUOo;6ekIP$>Rh[\-nN+,ph ]3C1"AntH(F?`s_SB6CLBsh7D@7 ]SAJd$j'.-aoYTsN)r:=>*Gf:U/! -03/6n&B$JBQ'70?@&G8eDUk:-tPpsa=-<W?3bf%d&Koh4A,@GN_<?4W^k`RGggM&'QM>lYS'G6,^t+WNDdb06]"EpeqtZ"fq=P'"pUgVY*r#D"JNmJXs1t$;P0;%$ORIhWYeAbL@ZSB&G'n4QD*L/nS/^GS_9?9>N]3fFnAGr!neR5=_cYH7$)Pcf<Vf[rh+C"(2A?.m,SQ+:A-I-BU-Kk6prA&+><'ls^\6#l5#gEl0o5l784M_U3.=W_qGAmQ*%%^^]6j$/S,O0"1e5/YmQMqj?<-TR!*0lOrtSkQA99kNQh.%r"dOm+eGSXYY8- )FeVXEH:P@Sa##kM\2&7EY$<s5^KhQmnQG,DrF^G,=/OC%2_K%0OL3=-eV/5>WsDC30'l"h>%Ar#"]CrI`Y2\8o#-\A+qnB[3Nqq!a+'Cab&_3WC@]2<t&.4h L<;A+'+s$<'rKGDI6KJZe]Yh^QZP4!4]NEjN/n9hb#kW#XXpnS2-dn=1gm/N`c6#02TWYWfT`/>?kr66f$mXoJHVQb1L;/"E/[_i"2A#O_@8!_onZ:KfIm25I;qhK"A3L@W2?$7>_J%UAKVto3lMX$-(b7s#nZRWJ C8^J.dqq^X+f;:nS.j'7',)boQ07P:be3Jja&_SjlSF/K<nWp'@7Z)=SVg/!4.7eTVUSKEJSNqCjY5=7sYiN6r"O1$L<O#M^$cd$0chZ.Z8CDp\qUP6q)9RpR&A,o,^jtm/N0n=9'pB6M1ao?B9\mC_6^i.ms ?+tqPJLB/XT6*(AYbq6*OOW"R+<:*A;"?$$!&::e&_Uc[%3.]iNY-B 4GU W\WB9*hW4>Cf]MlAj\q8MYh@X?E9PZEAhdOI9`bB0)DN3M[)i!`5iE&/6cP,K8fd$Z;6g0ZR&MA+m"ikA`$A2.0e5!2g==^N`#'j#rqt:\ _q.1dcbKhVo5QdUjl=<^Q%pF.J[KsmE/p<.0(?j=(@bU7 V`Q%*Q-\pdr%W@>etp(Y+?H+WbnN;JBNA)3Vh91?M<9/f7_j,B =E28rLFmb9C64o?NB1Tf]a4#GU:!(3o?;79.Ij^jkY+e7Q^4?[</gYgBriqr/`)CAY4'*/%9Q0HP#:ORK@s33FkJlCgb9<U?GTBL%jA8O=_5('CMLTA70&UYpMmT6`9!^%=) -[\Ap,eC?"[KcTVZo*^aj#8lV?csMNeXQOL@W<X(KW-78GS(-=r[2G@UH$_Kt0'4!L^;Kf\WjSATX-3>f:@sFiqGiP%`n/f*IHLa0CepA>VB3hJgZe32-'2hf$1) BHM#5PtgK<M4V-ZLLn6<?G;r*RP(7HA8MJWAr<g_.G=D8TO]UqHBsC/[eX"2;6oI N!0KiD&sD'n%a#VC:KS&_S^[m-Ni)F6n-`=,6;e\pi^cPFA,dY8ASA5$qK`dX/`1_[NcGQ<fmGR2X%\GL7%A kY.m<PYmWa-2t%el)X1pfFBI9Qa]MrLGA`)M,C\:G1X"_=._#D(p!q r'j=A;S?Rpii[4m?(kWsVD gTfDUoqdMRAS6LhENjl_;)]E?c8C:ijTNm.1GE'ia#X%5HI.)F^odh467(9]^j+aG7RqZMV)nHM" ogC)aZE*_T%< AcoZcCb^7eNZ5A4m!_SoA(.0-!cp^^X>/B'5D_/qY1=%*GQ40 `k-S D!DtVCL"a9kLRr;^Z\S5?4S4abC^_Ji.9=:kR\r=)D7H=.-1r.OZa.N"T7(U\snk_BLVsX%0AJ0_%V'jK_.e;o,A=ercfJTZRlB:js__+O%m9/`Z]`[CSU4%e<4T=F3<NHZ%MpF.Y.6g V*5/%!JNXEf=4H@B"ST9XQo4DQ?(4^B-g=e7?);3%=(ha)D$5+7WeN]Q@p,D;J9+#&l=>NGa83EIc^MZtk;J[Yt=&hJ'$PTA#8 F?B]XWF(CAKpLX_Iq5FWSe5._?it'%Bh7EAbZA"95NAo;_[WE/Z/0bGIP'FkIK*/Ie&la!C\nR&'>'c'n2C(t-ZcodJ" %s04ZBVLT1<F*q+D9L)qCWLC95Cn-AHn(W&Z&1<lAA3^faA Z7ae `\-$3LJ0464>OpehGq-lKmTD1(1"Ds^"^Oq(P?^66F9X\HT/&MUTcM 0OA;\<[A=d\TRPmia>:qdh@qi.IOBj]HO#"0.h%nSlXOGY[$mrSVp[Y0NICa8RL-.!ClD,90Hk^'k6a6cin/Zb!&je^@+[00bfcGFG(LY81#7tpAeR6Lb=qT_H("eb:YOiiI6hV*SF3:9iQ\d qs2h->dl6OT#PDQEbJX66i)]FtpBF -g/J^S\sl6n=G'Jr2:#B8)KM./9:S]Br[&7qh*'hl6L;"4f'[e8njR^#S@J6]4DAJST!XpW>?UcZp.d64.E#fAR#AQ"CFqY2BZc+AOK2VqA6I'YgjrfqW1rL?F[BD.fRm6+@2nsc3/liS%:$83NB]RUFI5I; M14H'Nik4^<'eaTB(=6L E*d$(CG@ >mUikAR:"3Pqd7$'<r\pUTi_76GD_e>'eK1^GU`>aMY*;?gnmc_E_1ct+b6LWJpR_AJG$b&?iCaD.R"S7VkB*<VpFcgg!`Lb-dCkgMC+iM`2Ope$l=55& Bq@niS9@ _2Ap!ok9A"(@#7]2DXWN_6Xr`$E7Kh!+"maYk>8&"h`YciIiHg_3%54DpD51IWl=V:5@t\EJ5I^8K3%8#@l85N#[C#<7]!*1MpRCS44&TfRhG_?BH 5;)CoIJsT&m9KBB;C<;WK$?9r(h$W0X5=W:_B+@W>O@dJL cU' fH,8;M<qL1>!O(08I?W8S [oN8c\,Cc&'bP.;Bh&(+$P*Xq,DmW)Tt t/(Q(EtlLC:fCY&XD0d[BZO0^ht[APo#Egl^c<\Z"FUY_A!K=j8?9#/N30Kc)n78ib8?b^7cU^(fT@q:%(W-k-FdA4Q\_8r9VB]%SP]?(:>DYF2H@);(A:!2$'QhpD:B40!K.BBlUk-,W5T;#QD7=Q;<jf!MrDGJ=K<n6<VY1Y.8tHj2Bbbg]Ht>k5,$:!,OF>XA/N#+ia]dUIF:!i"9tl:a]$e2=CE&KdWFBC0mA/(%d$qgD#5=e?R=S]\$M5jm)EJE4McR!Y`olVI#D%AAe[?*KXS,b":;275`hGb7QpHA5/'sqb,m@pXtWq#WC",L35mH[FD`P@mTP8-m=nQ5lOpVobKa##,I^iK=Wj8SN@^^sK(]2\<@W8oKs:<Ur8%E?i(4?H5(,5GiqX]A4:"rD*\cg!*$*(DN[2IaG:l7S+(K@%G%XGLW`5ld VRXkrEIJXk@,6RB4RBbrm%i9rYsE`]&^' $FpBbgjj8[a*F/,7*_Q0"3V"e2_&NW_Q2nM?E@(hjd1lm4O94'_6 IAJeXbp;m,!<rdWe1P>(J?H6I$k;(n]H1a*p@P:1+hdYQbTi.8>:j.H]q*N'cZ1a,a.IsC@c.rl"*q[s8K,kg:3PM?:t #s81l&,"5]]Q%N1H`D\WUS+AA!'\2;4@Xt*2b:JI2F@ERF@rem +O2.!&L#sAsZ[U]B\O$p^=;_WUPcp $-W/#_@jmh-kiq*5-LC*i>Q1)>7N;k[_jqJ!p^%sYC^*h)k tMUVh7E%P&TgZP\B_^1/SS](B=e7C3?%C=f$$?D+R-R2W)[ln`(Zn?\/k\;%j*+_;/AK9iJ <Oi%Z0 ?V6rHts7(MK<+ZPCpSA-t=1pS1!'YP)K5 jOt[G;.*.c.[[jGh03B<f0+^`f8rL oVGHDla<Cd^4rn8/VCQl.?m^AAoBY844K[nqc$JdKjAKfhFY<+n\sbEI%2b!n"h@,]*=G0Z6".b4qM%& \C5Lp\$t(nsNLq+*]^&M6=->Zb&Ic7UW&GU"b"*sU_@D 3Q"oHbX5;P3`UAAqF,keZ`8 "j6_fld7YUI94*YMRE*K99rnd$o78=?O>:Zh_ LpQ9F_L#^A3QCQ$Pmt8>N^W.)QBB#b/fefCTOO\/C[DbqdJN;iQc)_2K)i>tEN!t#Eo7EFcDQM*/Q$DVq73A>3q"?rs,DC^<@Xa*UNT)3eJ`p,0@eB-^MdL]-+AW?+k'TT"=*QA_6N#0QOFGW\J +CDa"d]!*[O+l[\"D)aLG*\Uqo /lpZS'`25':Se#*7@QG@>i1.@tN\l0)48QCp,Be"c7Vd8C!NOj7,,GA03+k\JAPm6'EkqMBeqlI`0o=jW2AD#Jr"eLF#K#DMXTA?)p\WG.+)@aT5$rEkal[sh#f)7D1:N<Wo2Kk\#&<^p+L1&rl<7:c[A/VTdH0H$OqA?CSCUB,$Ih%9r@$sScs!?q?k+r5p=<A\o0H*]5*+8S[?_2\5?_.-q0chiLg@j!bc-C5>@J.hLlbZ5gld*A%!]Nj+93+Mdh;e8oRR@(OQdp$:KHVG"_>S+"/0$AKK"iET>q4-g$g`'GQA#O`iA Qa AP+lgoob, QXf&Bm!5/(8N (/Ht#*%2/dPin7^G+<VL"?`6]PG0/[\I!$#;r7AI*Wo-4.d;g^4Z<UV9OA$+<6Gkiq%?OacGhT%F"\L0@eq>o0+$6<8RAVppX4`\eo>*RtAe7)'dO9B[GH:)cl<Aic(Z-4gZeOn1Bf]<GN>g 9epr`)8M;m#ftY:ZEMI_8UJdaqj)q ,h\piI:L:%#+*+7o.GkgkrmKBU"`WMJ8$XMWK=hU/AR ZC4IUaT'24[l.XLM,/.K,qtV(2cf:]Y#G0O_92(ALUY:.'q79aqZ4CV%P? VF8qc#^Ss3fGdSA>8SQdK?;MTW_UK"kj2,F#_OA/objAB^k_BZ%re/blK+3Rt lrAJ#ZeACaIA(jh \(Ne]R_`BNQ>b8A\P-"/ABZ[KA38!pWd00d"FSX/]S=CB=,)FO0QioNX76k`K:9,YD5HX(arVUq_-Y0c<oBV:]!(R-Uk%n;P[%:X>o*V)Z?h`C+Tt1o0e"@m7SVai']@hMG\*)P9M7S">c+bEkkCS>Hlot<dEmi4$KCat_n#)QhYAUUKX-ZU*4O;D=/4-OkOYdbVm)Ng S:Ia5MJ),E33_<^dHQ%j,t*#?M6SZNUT#CH<\a82m22`@NpdTH>(1[6)^ZVlAKE5i2o(s)rskb3MfU6lYlss3&96[M, .fSc`*OrF'.Y#MpkH/pde%<7m:LtYY&V)miFbqegR7Q ACrslZO^J@J*#V.H"r5m]5j.A.U7#82lN*]3'<!G]\lU7okDNnGeD3YRjJ1.YIi+W)nW:5-i--MgT9A]`p4b,.t_? ;_a>4mC2fQ]*n*`M>JZYCoAr6m[s7=V9Jfb3U3o77(9XYT;A!MY>ke"ni<TYVJ$6k.#. PMphNC_J*bi:DS"BTb[CZc92qjomnC;Xd*iHA3@F*C^Yp?Fa6>S2[0 r*ch2+bA U@j\VAZrA<6[4b08g*:-c&ke ?fU9+5$ bkkDB#9?FP_C5aTLiHaY%D7#empaDa4W%`KV$<"tD,H>GSLPNO'TEj./\m,jt6TWP:*hT'eP[<W)cT-K"#@2O@.C#dEaV!A\h\@(LU5iJLWjgk"!1inL]^]7%k;s3HGl$bs-Mk)q&ImPWb1\p7jGWH-6al08 67ZKC9`jDpABZ:F?nP-KfGjt@@\<m.HMP"(k7$2,3e+q,IaQR-Tm\*nqPkoSZ%64aR5s%Q7!3c/7[5`]pq;!q17Hl7@tJi-VeHT5XatX-9CAIf\Do#rG#UpnNVrQp#.=LA!#W6N=?RIB\fL6,b1O19VkE0_U.SI.OI*:m=De4TA9"jm^`3-6hs8&XPK/#WN*\T/s5_l#A7b18^Z`?@r`kP=VJAG< ;7!O>?V]-Sr_AbFZhABkt1n?t0*Es"WQI1i',F#/=?Cd<.?!LhStaQbW0,1DS"<A:Y]5rIq'R<[j<!tYP8^mf=,n[J"]>V<@dCam7\A-[<&3qo:RSSHB8\8qVEAlG8n#$fbnV$5RHEtbD<lq I1CBc)ifh@CpL#$[$AVq%7I"YfVV+^K:it@'t@^5PhD5lq`A<1T61d_i)2TgJb0RCE2BEZqKOn:oB3 Z6[HSY/ b(eA/nt.W^Om<-r/h`Xf^dL<SLaoJ%tK^WLVFCjAO0oU0J]]!Y6sr%]A00)e.9kB*Yj<6 bZI#G&eR#Vi]*2T#TM%VHj8+qt\f9AbH_7s,e[=Tp<iRPNO-B7*iG#U`jpj;,PSO<(.Qs.t+a8X,1hTI5%r?MrpZp#g+j70.j@Tlc1$1nP0&LEYlbCUP/NIW:PG;M<fP&B_rL0,h*S.Z=)0D:!!a(RMQ4'6W%E6E3T1'n@ /XF8L#NI0 AFK(g=AQrfq^?2BCV@O`OG)#lh9+;` `9+"7I2koGTpm`iaL=k!A9tDY"d8WsCPDdpNgU<9P+OFS1cgZH*:2q6[3( -[\HMJX$X*W0g::t@A/$-KGm-rc7=q)-sOVgn[^AWp(r0<C.Oh"iRpn5,kGV*_n9Y\hoAokJ>J-6QA%J,OQ47n@#mO1'2Xt)>_^oc<S!2ZnV6"%$PHL7PM)"]'Ng_5UHp PV,qf N(D1E)RW%Ilacc,MGe:b?aZp9^(mdb>foAT>Q`>GkdZ$<J!gShtU\>$aM-Y"6ac<j(hL[_\c((h@%5nT]V^,]M*JAblrMZF^3^S#''^s![ehKE,E?]mY4+ql<F(iFD#G,6XdK.1ZM%j(1hns<R!%".-XqgS<Kf%Boq;^Gg&d@sq` 5i_o`;LQB82D+VEn=1\,(, t<1I1@W`$a$"Gd08n).hU)2jB<!Mj6?.NZ7^a/TXR$jBM:>opBLJI!N`qA96bBoap9c5FR&(T;as,B9.D)"6n6A#-Ikf8YJML?$N?eT@_]@Y!R*B!J&`0!P#IW6I`eUO>qm-NA/W#hJjN!M\>=%iXX)Ik6;G`Rl.BJF7b4+Sd7;q-Etb0Smtp`7/02B^]@7>GHJn9XdWE1LL'bon0j)f7=9-I9'5gi)-RHhV?Y+gWL .W2*XAT-qg6VW,)3>(86YA\cIc6%s(/M8FM`/3>#ak<Ua4C#WL+-6bfKIl#0jl`,+I(=Q7B1=^rF@(_q-n$P`Z.a3E'?c X7WNH?I\&f2ip/bK,9XN=W;T(N2j<QVCHfO(4n2:-[ht! U7p1aVBs8e42:djpo0;b-?*DZCl1E7i5p^pfK8h"lW?9VJ&+^c`MRtGYZb5GN*aJ?I`6;9!ni+?EW6cLM[t2!=P.Jel)#;_)5N5ThTGQ6I?a;$H>aIC>"I__#?ls`7PJ*Q@RZK/.-%%9to<BXI!ADAdKFqc&0AE1GX!^PI5EYG`ZG4;E+[!2=&JWhc!l]<&hpZ%QL69.p8Wj<M>T/m/V'"YQaV1kf-Pg+$;\*grK1KD2aQM1tLp`T -V+qXm%=$@/%'k(!f?'HY"9")?KZ]<13,lPL A.CXOJN_h5$m`%a[S)fi,2j"C(aAsK#?db:m2EG\ Bhq>Yn:VVQB`VMLIK'P&n$- Scm&j=ilONY6qSNS?@j)'s,(K;K%\1m\A$Y'GHCPG_sJ U?+S`cXCrDAM0_jq3.q#R/FMf2JekA0bWY%UPQF>E3g&TmJZPY1 8bj\Gj^`q@#!DMA+`1rhm:]n!D!V#.\kA485=ACZNRP]m"]fhcJA.@&14C25=Iq]FdO7+XWe+ )S*qre%GN[ 9=$t8,g! $l.1$[MO+FUXqq8o$[dpAA()4[8^> 5p-9i]L(Y=g:M%.EM:nCF6[O&"B4;MQQq;\E@t'/1,NZ>:iXc6 *QXIbbU<Oc+V-,O(E9]%g \kH *AS5Htsg<M'pX3A%\&H%r\=:?Bn*[iFAY6Y&,sd,t+EVJVR\4AfB$0c@X,N]B?<d3^sZ=rLA/HEhJ8!sM4;Rb9AYGtfRk^'R<,<Wb)QW)K!nS,+Ie'VhJ@N9$.0B>MA"[jV`iAVA4i%HC<i*. &qa&MQ5;GiAkM[Vg\]`eA'Uks_7mFc$T6/(-Ma_8X:p1S+L@!91Yk,MOm@l,k(HdtUM<XS.BI(/+/^7)gh^7f3>StaApU?fs(_(&c-`?C6W(TD:QAABR;-=p1VhDKoQC=Gj_DQg@j?;_"Vm,8Bk#OZG8sCYkii2AHa7'-Eet/>Z`(hFCN ]Sa';LE>#qn5:!a#-WGAQt!r'BAFI:B'r>6nqn<E?rk!0-/@>gBVHlNK5Zf>9VQ9o\*Xi(1t4lJT  p#YQ]<TG,Ci*=SF,A,qSR?S.Ki`]W"RAMPeWBj0Bn>1c37h`mP-8J ?qRg['1UY2!KB./E,`BP#Ca-RNbR5+#o,npPUNdCp]@0Yk\D1*X/+cog&LS9?O12P-:.9gk`)K#=SWI0]RV\H<r#VC#F/=5+(i?"@mIT)a2>i]-b\^N&F;tUQWBTY3"[94O!8mc`?__6,[ATkf-X"-h?Qs1hs\1&AP:d9R\!Q]Ul&r-NgC;&D'_ gdX%j hX[hk:p6khM#7'8s'/AfS1.;FFji7):shg-1?LcP\*0cVT^/g.4WU45eMOms'FX8+ihJ!\ip/>)Frb$pXtIYY;U.]q`XC8'->lm2?0l/_9d$1R#Q "MCPLgc9t M/hASnmMmK[nMXJ5-Usj5^I?Ut$1:O@FYsRm*V<@2W8EhOA,g_Cto"2b#p_"m[_^`Yr%O?g);KE,/C4+\;drM)$*$UZ)7_.:DCA+k2eAk!sB5[I@5m$Or_+:#^`M#L%M<N-pt<Pb12Fg9[i/pFF<YP+R!(P(2^.JsoUF;5fOb),s^X*j.J*RXD0ei*5&U:tW+DQEP7RE^d>lj&P$XtBA1Z>4S[rf) o;'?;E>+$k38#JNNke[RO*!XBKMq$RaMB%a#]FgtKLWndl3d"OF;/OTY'2a56Q.TpOnBT'c#52Po"N jpRV YaZd6\4/R0E/ZY8@G*epS7ja&_M4W&OI=UjQFmR:]kma"f_3CrNdepp6O_-k&+Vg4-A)H/d,@ZZ;41X]XB`;3))Af12R8d%nqj"9g"%XJiKUWM3'l`:-9<(cc8/OAUK,G[f^iOMoI>t.At&n[(+Q0@pq; l4ket*a10XhApT`(0H@Mtp:UP=5M<$SJFm%r!/J+2h4?:e36P[]54Ajm^#+*R*=eW19S[$&(psd<P*&C`"/$QTi$qhqjKf@,(6sQLg@)OhNOmMU\^q+nfZhESb*&7(B1bOMtI`AgYXJ$[>MZqX.P5:'G5'@\-&NEk+(Ptk/t;b7O"'H<+Mg4*Kh7(<MTi_Gb<A6TL,=NC E"s]eEnolA0-cKcFiqH^\K/pDn^UM[`$;7)X7-=eWXa&l$<5_dI@(,UZ&,-/Q2K+ObSYS(&4C<p]/f2NBa H>c!nZNQ=;i_)3iE:gDgIl;a^f/l/Z!7j$;p16Z4rqp5]8<K6T`5PN:>8j[[>1\?psffh;Yq6DBt7joW#+T0E$b:i]L?&"LR7`(N1cS^a57>O-!LOG^M'bH3VqY];-:dCetc4UIM`ciab,_Ek18dYU"g';'"HKbF ;>fLTPi7@sQ-&er``/-X5C/A.G%q:e/I(I]dWTV/BAj\HjVtZ>aO,gi#o=(;1D%tds3@\T;ZDC^qLV:Wl[N9i'=VWD!j9P0hBZmE>1dDqS][[ABO)H(%E:'R][551":,UD$*U^`lU&9WD=@eD!]R74X#qo']*FEO3tkId2eEb"=cea?@04l ME%QZ7oji'B/l`r+.F>9@/c@dh:W]E9T?e2S<Yo,Gp%U$2CM=.>?W"i>l/F;f9jF9/do%]S1-9Y:sn[8B.!ss^bHB7[9>TQt_n7W]2f&IK3KZBLAR5M`-:SQG=Nm!^2O=oXjQmN**Bbg82=,?%1 ZRb;4:-tt1RM5T`%)5X6Yd'3`0c"UT$-$$ ipE;cs9ng;KA&- 2 p\0#/YI/D2S=p7qF%W8kD9.T&E>4[d_;s=(*H>p,ReVW<d[h#+*4&'<fdN/HdeK`ji'?#D@jRI*dG;m&"=]3H&EJ;*^i O9:s!CO_*!IaZ]n$7ZB_1jI(s!oEacM2KkIj:oP.Ben]O8Gan,JDmr"c;<p-^0phslSp"8lFX%XOrYN\1>nLW-U)X!.A.pI'=Zf*SapAW5/$+fak%QqgRL`_U"CA!@LAAfjE-Cj>A,`<?m+,,W3XOVQr[kTQHY>@1$PE:<hYtW[p$`M#r*Oe2U1p"h 3j;Sp9"p3gY3D-Nr$GEk('G5_Rf,V>LSf!'FjLjR;;g%j?P0?LiC!fU[AY>TQnp6[*!Pf60],b_%DI/%`CqMgDp[?3;P`M#8U2BRAm_^PQ_8,cFB!O8*ng9o#^::F^AU_JTUH(IiNs3]a9V;01;<7Bf-WaN`)F^"Be0RQ7<nM8f`WeW7OlK9,LFD?A)jr7Ji_G_R5DCbgAP(JHf[c>LX)oAFlTL9krLkY`V;_8qOj>k#1;Qg=@sNr)I&/gAgX lVbhF.FCEGo2ChEgGH0:&@TBik&Tb7[``d7T>L7-_%:Xf2n.ldtlj>@Bd= j&N[<HNAi1gI]OgCY!+MblZ_mI&98MP-E'0ToVf(NZ[2m+.<SN[LUsQS8bXcA;8%TA\I,:`k,&1LVA6dTCE<AVesCQp`dF8$ ) 7q5(`K>s[R@5cQA*o^WAB:%A=kbN?pS14eFM#Y3Ls[b](spXdn>7[1"(8XY91\g"8jdkQ_)P[FE`O9A?,!ZGs&l8>%1%6EMTA_qEqsEZcH!ic:.=[IP^7/q0"JX<n-A5nZdH0gr(`sTAQli!se0CJ,EY/,0=3a5q<PKSoe8Nl%HfarS(8LJC9@RgcAf];$7l0jD<Vn#VNH?tE"[_B =7S9e-0 Wc\#MJi,8Ose^;i<EQ`-qA>Id2 8Hs+2AtK5l5ZW^%h8([?A38LIPT`PAshLUs,''dC.6i0j^l.'U%9Z!"YEal*$6s2(N$nM21&T')KNc];JP,K1AZ&HgQ5g0i<H*&1UYcE2%M(".phj%9E3sgKQj'A0lU5i1@4>;@Alof@02jOWXa(mdOktRImheaBTF"+_G9S$6RSn';FoDmm?QeSKHkA7.DfA]b.Fi1k<YM&OA/(pOL3AK&<natm2/qhjT@D""tnT!+S&^eI#74tY_6ASAaIN-fMR[e#7SP1icW5_/MmKZ'2?.S4U&'EmM^qn5K;&+tA:SX.m6K(Ts6jEn4[YNB7,IN44'tVRH4ATc0/cUch;:4RIIZ"t$jRq7"[@mSkpqC,^E0pDC^8`%Phc6@)<+C`dVtPA,j*Kf\QeY"(BYU`%^]5"LpL].bZ5j2&gT_Tp2MB.q%aV$PRl5eH9eon9S[3%+E,,o.Y:,g1C oQe_.tqJH:T,"VL6=WTKB0 \)C>1LBMXk'>K&Al..qA1daLmIQAgD =bl(WW rKQ^kg!0_HL08,_&coL3"L)8Zp(cm;K#J5-)#V*._78W_AR($ZKHP4-:fPm0@/k1!8^[BXSoQD!o:Yrn2"2T^"Jb9s=UDLX5W@Nr@'SmXd'1c'VspfP#7b4@btdUBJN3!^Ye@n\;)Sf#HeATK9mrVQ;='!-::"IJk[^1n2Akm>Gi,e,aIAZ783dI&Ns93`,i)Ml@%l^Z J-sqj"b*a$$9Wj?h)>a6(0a4@^a`NoF>EA2Z"%6<RnnkG*bZpe^^Kmon;e?a9sWl$O1_)AKS0t_c=Ye$TYTM8HHQD<&O>O@'9%.2PaXIDk-MB^h`RTrFG"Ki-]4k,[2kB63/da"r,g)*cH;HC-daTZ_,Bk] W:? ?`,e2`=TCLJ@knRUkoM*i`_Ah9PKTTIatn#:pp0;T_kfn+$c?Mq\S$_^Yj/?fOK^&Q$-94\0iF%'8D/C*3@@Xf<aQ?:f \JKB8lb(1mk/tCA$UK@mZiIL%OMg[6fD5UTM\3KXYTI3hV+%[AheA=3DP j-)h7qo7 0.P;\)p1DE95)r"`@M\&/^lS<Q"NEn>cGZ;K]E*)T%llg]b^SLSt Vrdt4)Q>?k0SQQ6:Xeg@pm0]1>,TnkC s&LKP5n:EHp2")g='d@s)2;-Y(Ud!A-'AE4R dVZL>MT)q4<'9Ymfs*9?Q`d)b2H]Om:]r+Kn`gt"_>:)t7!GA;&6'h'-.\lr'erd(b?#9?9Yk?T%;AXE?=09Y[DSUh4)8HltINi0J#b]Bdt"k,Fb ]NBR2/8_AtKDN06M,(Q*0IVE:pG[%)2l@A`(R$%8frtGF^i!6c*[)*Mc%?+6q[0@Zq=V^]`#/U&BT_'6FD*mS,AHh["]`N(QVo'7Z-f,1_^s&)nG!,A4j53m`k,%Yl0i]A2S<lVjH_)@P*l4Drso-5,1HPtCnP7L<:1-\M>6"DHDUN_,kR.66#dN];A$\_ggOGpVsS"p9]cN)rL#C511GK*j9H(K(0dqSJ]Gdb5A!Gmn+hFB2]jA>'@8iscCUTqIJ@^Sk-GT'pR9<P_Wql2^,(O&'An3Qid<k,/PQA@ 2nUm9,%OOK=?TT 6Ei4 KsKVI[H4t\0 cs+IqfMO)U/PAJc<A>Ahi-0VS=^@dbe%;!On(OYba(j[*dJ>5b16&<;>3DZ2G L0,]6V$0)Q(fK9o6g&439WHT?C/W&Mkc&&&7g2V/Kq"_LqJeGEJA,U%Z`^$eT reZ34p^FaPAKF>]3RJZ_,)>=r\E1 I-K)$b+ -@[&ZT,mc0b;C4A@T3,]Q97>AC% ZHN b"f8D *a(! YCXb+^Q8j4V6+*:<]j+De"ZeR(fL(/@Njn5'&<Um%&YssN+Z@_\K:cBZoh%.pLKn0Ho>JG`?@f.$AL%Ht-:iLUCa*hl17k([ZY\MB kDRh#JS]J.jt@S?LBh0SVG`AN.?!gqAH,4DjnOmK&iG#[P2X"H!fb(35A[cr$HLcY`cp^Sd_7N[]@o2i9,N9Z7:STafZ@E>,"oXL>W""!IsW`n'9%>O9 .]!-O``>qCK02AHnPOA</-Ql`?=`e>YDK:f][ZX;^E.mF-#JpSNM45q;7Npc;JsgQVtD@dnT9n,SN4Z_8V3ML .Bd1brK:0]9[-'!?gqOl^$g9#<IWS_Ftih4UP1S:e3D`&2*KVC=ae#m5qe>he@F/#0AFi44-GFOmX;1Y:ot=40rm%G)rZAp*;A#$]bXcR)FL.ot!/ HGcOY6eboK>T;c`Q@YZ2)E95k0(Q]Qk2mG!lA;3=?"f+s>Z9gOJe:`%EA]IsP^bL%a0'Qns/V/oqN*X\A*SWV1 7H.;U)V,f?6l26J)'r9%S8DHKYBSA'6>d#Y5bHErPHIH)h ; dcmLG9=WNP^dV2+N;./c>/.'Yg,G!Z ^"c6S3H+AJWf =i\^<knMeM?pB_D;qdh5fq^[ ?H-5Rk[OE6XOZJIFDW_bsc$d+(fGb&32K],qn3L,WIrs?9=/*tX*A8)t @$(OZ1=.g'PoJ4$h!jLi$8qjgG&TO*:TJn2(IqcWXjaY@LYbT*Bi#s&.\$^XgkpdF+o3<N%X+6T!WEn.s_Hnb_bo_>@CX$IFJnC(,AkAGfY;jttXd;0K+,#j 74DomGDbk'5OeaYs;*0R0b]$N4L+#f"s?8$`t9;OG%Ya@kQfAANhdLr=qRH:2e"T)/b`Bjg(gD( 6Pc+^[&VdH@`B>"qJ8NAa]8A@t%qd>[l]RHQ]pZp2\In6]5?]l%j`&A)5r2IQM:;Y9rN+PP*lL`ZCP_@tq:r%T?B_$39l r\hehLm38iF,_7?jQ"=.\Hs^+nEs0Jp3[d.3mjc1]OH#`oM#1ikiAL`]8p&>Y>.AKBB4KGA2r%(Z0K1\QW7!X- =.BLhN=d3as/*B^#MY7W>5hH,55H1,tMY9]Cs?H4/6da 2JSJa/t.(Ms+LPPirD0MXP0!NF6 =`!+`A`RfU,&d3Q+lK`,e)6$IcpA]r0mMfncKc[1WetLAXiV7]U0AHB3/"nBr'kYZU_/3:joQ-*(OE.2,@L`K cM;WT3sF>(s3=-i`o!-XdtHROf@RQK</!?qD&n$-jMR,\lSTen a]8`GT_jX!+Ed+Dol3L=!A^&ef',Z]pm1`t'<5J!0UP0BehNE_0Xi@qjBF$#on10Z2cW?JW]EC b?QZVHjIbs>dIh<+\b,GY!d$r.8ho5%KDtFok?`?bP6:T+D?(qj_=htP0r<Do$ Zk8%:.!0QRS9c%co@b$"\dEYhQms7,>*[6B'WEt"m',f^<\`noMW!_e!c3Gq")i?spm/#Yp BAQ2jmc9G "]FA`L@8h<aRV/se"2iUcA<?e).bMNmnQQUR9?bAc5>2aSZ9X!Ym`fKQg%ViTALaF&-3%q/BE(s/%`A7q_lf8DJrfgT,'o_(dKBR7j=o'G2Y6"O`<-OCWTGRV/=f8HPB:d_/tg)@'" DjV?mI%[4fE^MtHE8eeH"h2pS./3#@Rt0%T"-"X'aLPgmk&1WC7^$e,Sq%Zm;%.+=c)2MMg2@k1JfBNFJO20-$D=@abC+kKf5`\-g9L:tl<SI"+ZGIH$\D_`2%jb=\G9#L@"LtTjSP5%t>l4(mq\6X9jH(?dUVK#t>9J]H0?EtAO&:BW_pV(mCX1qoP1&ArT[oU_NWphc14NNs60UO9]gbTH` >n!IH%IO*(FaeHm-ePb(>t<i1$,V*-/DnjWTK50\H\g.:ZCnLI4e[j8&AOd$2N:W(ejK5^9#q3EF8@5Yr#*jIV/T=#n*iDS2at#GX]hrpNYi+d RpXW30Z%":PKTG,4%Oe"tp1(LmY#>'beip%>6(FHP-)+JGN`C>D4ffmfcYsWcmJXBpOVON4``0Q SHQG?@!cW/hoZ ']MH'^0T!5"(i)h]Y\(9FTfJV:4Q&ac[Z*f:,@(pL'T@0:ooO73t*S.S R?@3gc+=bcCM%M[$P:K<;o$J='rX9Sr h(fI^<TnMj6)h +1ph7O_jnp?sn!5OoLBUT(f`ICL0jFGm7LOhSRecX[UU?B3Zjl'K$?,V2Mn?2`[X!4n6Z/1st^F*\G,Y5:SNHYpGcJA(#'RB_$gW5gV-\c2F$I4P/+< [$j=j1o=r#'i#!RgPKn<W>fR\'E/#][^@Y$OZBe;-88NUnS._L,N\$5cs atk#T3A$ffIU;''(A$%rrsBGD;)f.Ar(>3/\BQr\Tp@LX^_71-\)@q"5U+dG\m45Z[RWI,RY]=UE=nSh4\4*(F4K?&Y-XSFAP-irK]<">lYQ-?o.j_N5>#L:^aaA?%Vn8VQ3'@m*sF#2Cr^CNV!f"S_WMCICaMih:_?p]%MLTPB6C3o^&L!<13?gm_qY)o9;2hGRSJoD;Dt-#Yn#e;<1=OL7LD74Srmp5&UAq(t2;"bQ/\5n.@$kZ5VR*<d\hC3%kp^M]JHpV3Q@,QCs$Wn!bo%d&H@!eY\e%pIlAi+J$tPeo4"M5hT/:NVP @nkMY9n  E[Nl^"p6P*R&VU&AOtBA66ohb4\f(9jj\fI0MUm? i%\ZJ-$Ea"W0X,lm>(Pd -Uq%T`9j[S4J@*g14fA-LLted[D.m7f?"#0olA3Q8%m4KIoI("&Ks,.d@5.m%7S.D*M"XSC<iUQRKUHa%e%8LWNS#]I6]](9""8pJL'd'ba\l%9Rcq%n^hZ6'=pF7^rYsoBnGcg_T+MFV<k0-h'*YjT[-#DfD/L`6g<e#;Y,9mb>qp<4M^M?<`Dt9NU^!=UXV*Y7'P=jA.:-^ _hP5oYKAgO/-VA];+43=cTaOg"(G`@$6M-J*C2.jPo9)Z%IOq7K'5",U#XK(WTc:D*s0oSK%(pEl.Do3Qof+P9A"Gs &o-20FR_;G3Ab:KV!q>'JBX,2'^>->L`,,8odNI"\<&PEk%E99kZB'#\R:.bgbgUj5**>=NE ok7F-:0.&DXk1Y_h(3SI4ki"GTe@%(rc=t4>jk#o!@rTC97+bJtVnc^[*tVpW*6NIZC* ;kAf*))ghWh+T`47Y^6h?s<P*0ds(h*"8Cd$ ()W&_95S)U9>t\MZHTgTBZ01;3;TQIMbjC\PA]r0$D8Oj3>n=O ?N\)E e>a@\+AS77?%N1K[qjLVAgob#IUGIFa8lQ%tCBIYXCjf?iH.5]j5+*!k&DsG_E_H+Z"(PJ$+l'PRmA XO>5BpmN(MqiNP*A,@?9Wi44tbi4'0'W55LNmM2AZfU;DGU^l,g-XENS,rh"ZU$E3\=S&DAEm9r;i<FbX]ZVKNDr!`l703Cpq=jl^0;"8CIPp>K^N-]cF?I>n*ZLbA`2<5[7KBDLZlA1r1%ls9R;oNZJ.9R,]eQCnhBnF)bUL&L.?RYSbFONNqAka]OVF*#biD75m(&]@k6d5%dNiCs#NN=e\=^itmKL*UX )q\j=hb'J=.s`QV2hFD1K r(oZ(lmdXR7kK9`j?MN7,ghZ`<YQ,TtB7r7Xa:JYSbiCrXN8\iL a@gA[*!aE-e6pQ3o_ef2&g^Sk7'QH5cs<ae2%L8-`g:t^sG_B+g!92W*DBZ\:@1/47O]Sqk:kORW0F%A^<;W^/A%bkjW \&:kEh#7)=+b\kcCf\=(JII#_JN:=K r<N'^g0a_rc)B'F1B2%1OdkoF; TbAF]18 UK#TW>r0N:_>A Z#kS(V*C Y7bAeYGTpK%;tl6P!>Q1W!SKT\FS8hq4MV*:leK^H;N>pFkI0)F9K7MZ1Jpi8Mp2T\_(sjO!b-Eq2r1:[4%3V%gC)pmecS,cs0GP(/(l?X260AgGL9:&)hbAUX0q7Wl!Vk9$D3.X8#,COLJ^a"B.KbmT.*%eJLl'HM'i81@)>>qfq"HJ4IZ*e[&CF_FgnM]WT%;Y.H2br/ir><arAedo2\$3HdJ9I]8T8jm(88W9HPRp?rG4cs]g(*50e;0ZX?HdU] r.+TAAPXo,3DCZ)VsRB*>G-]="3TJ]/Z9&1i5a_DArr$d6ST?+ 606gF.trN;AQg?2TXfUmfNE0P*Tt&AGpK"*,,]\k':dVcTY:GPXXW=6\cf>C$F@-KJ$B6n2ZR6U tYkl-'1D\A<l=2E9TBINsjp1(&tsc>Z $"%O+e(QUcGiXAO8JtZ8 !K-O]NEbc&R*G)_:D^nfU7p->OA(Td05<Sj/%;M!dn sBZ=NFGQ8*'M#7]@&gG?sZ[j@m>*?\`A#D1&$Z,L7 3Qh9i)b=L737;!*a8$%j?Snd3\tr>gd\5tXUWs$!aB*-67+&l*TL/`G;c:^\L j=pV5:[,pE`tKNIm:"r%`b&^61IJ)$2Af86;=AFkQ'4H<`L/S'X.3[?VXa7@WiOQl'oV?Eg"j;m4Zj@$][-.4Ak+3DqADc8+<9rZ+h/%:6+OQ=4-(^Om*s"6hnAW_3tb=?H5>"f5k$bD]a1ULOWdf7I$/j6YeaFq+5rrJXWkAGL!;Cq.P&KD@IJR1 ah[nI- kM"l5=bj 3O4F%P8s\M4T:#aZB 0"dgA.V3*9L[n s>F+RW35/TO<.5iX!P;X@OVeZC=p&]LO1P!aGRn\!MiYF>n`ORkFbOenKAD!FKg.RNAl2jiE t;,;,i#k]n;SD$c+1b9'j471C!/0I RFm?:h,Ac_Pl8orLp4&A@oUX65JFZ7,;?$ZF$c)!Li9Lh/bLr]gCRKA#U)ZiE>g?jIrAR-d^Jom7ON9Y?^kaokCpR'QhF8M86-4g<TF8\clNT <WI3-Hd(;VkLg\V^AM;>=K?Y',qiqE&3F4,T VU8f`K57\j@!sO(Lbrm$c`GYK%Q$fn0P/,telXc->@[Bn!UB+l')=]A54'PjY3$-4870FO^0+/8_BDHd.2^4.`(/I.dOY98T0NA>)t^h;5*:+KJ-6#@`=B/t@hHR#p^m&k!;4K9B^4FMr &70R(ErANQ^7U 7E123;pZtT+72f69F>4;HDg`kAg<Pp0IBJU1]+cpM9Pl,Ae8X5Fo[Z9[r(hEd(>hLH@: slgm+_4Q@. =qXge<."NP!0A5]frD]s%/;TTUDfZ]*\p\c"HW$=&-#,MA_VE".&+o%3*P+O?E$oE>2o/&R.ce-ST6kE<U.G^PP<pHF?@OXAa&\4'.+%!%4G/?"IYF<@JM+WBRS1$"f;tLdK"c;a@,pAX[bc^p915SX a8,'ksR3:m'k9CE<1ltZ*"]4gmg]`ZFQkF,6CV7(-Q3%:==$$Md>ZG#;,8:E?b<`3QWMa>!X6NOT5CtIc9D9\h&YbD%0WAPh@#3KK;UgB'XOp0SP9/6T"mA`>CaBeebX4eCKBWtOc"'HjS6[.*YMZ5'm'R)_88g?P.cEnRBb+C7q>Q@TVX]a-DfE,;Z4n[0ZV:TGQF4>cc\IeJAlhNJ3`m4A.4;fOtMI]E/1C,<s+n.)bGHMoFpA^BZ/Q[L_@(2ddD2<Z9!Y*K@&_L0N9icXqW:ZK`RPEo2TM-14I&)d%)DJdpF3kFGgP[isS/glO7>%>UrO,spXDX^7pZe/B5@='S7ChLD1DiY]U6"VJ3"pUPJC!`A"2Whb4]c:.]4B3"#O+Z*4*%aJ8BkP+7E/jDcH!naD+iDmS`3QS%OBM>Q'cZAaZ!a#Hh?A(=H%k!;]/:AnH5o&JrV8.sZ%c=S0)oA-lG[4_Y2TT/KW@:^gtt$eq?q]R?)ZEC`Y!^O&/k,I?A3:]<`2:As186Y0PPBfDm34gtctp$8@F;BVd(,4h4[QAY-tH!TA*nY []?mQMIe^R"jrNMqs*?KF$q*00tT.l7t0M9;S>]MOf=]62.RG`arrBH.`(ZP5&3POn%=,aSEW >Cb&Zq51r/^MqQeX!a4U`H2]$$4OhKag8jdpk-JALjcp8M^J7*ga7J0!jTBPa AfR1_1aD"4@CUe9) k#T(*3WG?j2%-m8$3>.A02XQ$(P3>IC7AL:kO$7kJ'pdWi]A-)tlA&3 9dh@ L-!oa0r%7fg4i<\TejfAKt?FVHV9b&3Kc;fmBi`TF9f'\Sqo-J%`F8,;-&i3=B+F+>qWglV;!\T52SeM0X^D7nYjm<@1i4]j/X2Sj[L[5-8]r*^h2_Ega6##!<mVqc*E,g_RkN%ZjAJ(i]4:n4A>9Jpr`a%>+1RDg/9"G"@><RfJPUaE5^jsW+ds'QIDSaiYPc@mn><97=!nW>cg,r=HP2j:8Z%bM,3)&^R+=dqhRmLgL*p%Qd4cDnTJA_\kT@E=_^t<3 TbBON/N4p+ohs=)8d0AT&[[GU6rQ)U=@AS3!O.:ae%$^a:eF$E-B*)NC+I]RMb(OP:DcGh$/kmKC^Fa*(aQUa%<m.*8<;Rj3r:,t5e:\ghMEa-c)o DZ\fsc\/#Ue/Q pO]j?A=BILDDJ,]>aIhe@fTj`SO3p2hf^cXp],Pr+?^N?qi7.+PdZ.Mc7gKP".^,^M^>)Tkg,15F*OZebWqLVtmjP_'tX "dJgUs^=('a99?t%3is^Xc=b?$+R.TVfX7LQ_4ZsSs* V<E%#6d69WI>:bQRrr<="DSFR;h[*=Aj4j:3:3:&n$LA'="tGLIqr>Ho4k0[/k;$_abW0=ne4`NlXo1!VN.sA'5'eZ&;%9kq)#s!IAfo(KD+?ds*nYSVcOrhn%PFM%hQ*Zh&ArDNHq3p7TS&Ans>Z:;<OeJeGf+HmI69$,)(e_-TEbl$-,>@:a3:8-T#rQfUdad/nX&B/1%4SK\2H[]k(42sTnPa-om6ofNB52NMl('Wf\R;G!h^WjmtRS%`R's ?A^KUf<>E)aHs)mUo/U_-,1A(MS]C,0,3Hkk6QKWYOCBhMp"o.T/mi]3Xd8e9%296>X3>Kd):Fr41"T::Fg&<ht[WAFrshW4"bL+TmSsj."XRSW9gV:hBk&/'c.K_&G8tf.$o(W^'EjdR=m>k#S'JBX4p`d+5[V'T!rHTV!fbSRST$kr8^*s_4,n_HRXCOUb:Qh<:f.^A*6T@nb!eiPa$77Q;:-2lE=FC9"Qg<9>8API'1:-B=\_X=)8'UrRg<?mj%fRb7aE/'Q_TmNBEdX"G)KE3&(4C:]_$c (\83qc]!V\j`(B:]3LfAD!nq(0"YfM$i'(l:4tWSane@,_9V<1Ld">U"'4>V7Jr9k+lPGT*tZ((i.OfYj_N\PPQHXA23G5pC6NgFAYJs0#+'Ha`1hVf/>td- ]8T[c:qm^IkKp1*!c1)m1lYmKj@V"GcI?^ss;ZJAk%SnNfbPPI^>t:Bh-BaWK.l>W!ChHrtKEZ>ee_\MC^\C6]<:C$]Aa=PnMq(l%LsV`b&A/?iCoX;<jamM-"`(.*&;8'Ub0pM6Nc.Ua_F)ic9FIE,,1F1X-Fha"i#'@kO9P"X[I!oAXIDj)Z5Y0?T]PBb?HhAWgon;\ep1P]kO70_:C-6@%`)9N&2iF"Y>oXsj2Eh-NEX_'"$p`1SsA+Y;@/U3R"4TmTtRS1PX2-N(p(tE%E[!f54H X:=RX]04.tMH>kd"_qmXao4"PhQN [)2E3X5^KFGUs^*6nbXPPB>`*m_X"bPRr_j09<9&MUXsHee&m=pR[d4; GIhr<dM2n_H.@0eemZa*)amJ-tf7fY#ce/^ZiMOYQaI9q4`fHd\5ANs_,qsG<#`+l";l<1B*<"AC*SiJ`ljgt#T*_GXk)&(5FTY9`XLZ`p:h_hYhH-2YaIl A_fN+aBekG<`,nXK.9Z_WB!A&.7SjG`9@,`A7^d`9p'eFU8[H!9eHk;$#Vc1Fm&!DegN(W^FY4k(.mL;sFAZ4n%50%5SQgto935ehGtr=8@&e*W7Xb:2@ZZ!rV*34+YSMDFf8=>[^A-m5:MN 0BfKb"V.72m`$R[rbZAk)o r%KqQXP;kG6AS9oUk`rt#i\T4@'EhXWqDk)s2%VVKYrf]>lZf;4CrH&LMT-4_(AX"amL?UeerlB<NofC!2m4A5It^qM2.Obr7FQX ahmRtsr[gh[ c=knp)htn]=!B(q>:f&+"ko?:K e4m2!=LI55i;jg,-;NXPU3gAhbO_7Ga$,1FG<)lKK27]2468]I9NKi>c"&B4E%Ga!qWcc>A0Rl\EtN!dkfkBM@.+dS^`+nEAiaE jP^7"k5do[g*R"eZ!NM1_oeq+?E95+SRZbZW#mq/-p#jL65sA[TfB+V_+8YpG%CjS/R=eX]F@hf-H8cARJP-s2/A'A[s%+% _d_roE_7!J] qm>F1&7,=@0c%0o6NGP%BA*Fc9@jmKL_"Y9PSG"'FJs#Ki+T'cSb2 8ZA?:kYUQ[UTY_Cl)%9.'YjB c%[-c0/h!S>fOFV`7pFcXEo$/.k^JA:XAPqg@\ ?tl A(;C,llcO%HbKGJiM7);(PK#*6"df'QK@7>%_ils n(J=\(=2mLPK4#@.k_RRKX8qAeoR%-'4(#cF!Aa9^kiF8gInAM@1J#cHN)D]eUSh%.U=4K#<:R;]ApDS!N/UAA[@KPPQG?j'-5HoMK"a"P+=6E\#a)\/'$XH:f9AK6lAPk=HH6)&a=,[<c_('E$,f5CL2kVGUYD<;/V_l>L\[00iK8Jbgj-lqA2jX#fp^Vn+D"'fWg%pGM0L;eLW-]]k5a/fhh,#7`75hhR/a*L0;3pQ7P8$+le8YQ0$lGoObrc=N@fA`_m`^S-C-:e"!/GZ@"g2;(+*7AJ*K8E''4_Bh(K0;,)3, g't>enZq/"VbTGnJ.r`9Z<eViH-Y91GeV^n0VmM 5,NL -ZHCAEAilhWW9W\e])(#r:W<A.4rh6kgMj`9cI<@lp')TmB*Q% `L8%^!bc&W#@#*-iT5</f?nmFWLVAciR"Zd44T'E12K2J\$5*LSUoP-ch9PbP;1 X@=4>m\P@MV2Pg6b82'$X5%C*ccs,o8>G'2Vnmrf%7- Y<^>TL#be(V*ALae<3r30r\^=a#^o!OA"@F9=CAgO^nUC+*_%b:VZ<0ka>XB#,t;4]S'Lf[3j)7,Yl=TrK KmJ1@%QebB.J7 ^F=g)"QP,LH>45bAF*l @Jh<g4+[7M.G1SPE/nTA6PfmA'GWU?XXkL0)pMo5Z<Ap=Oc@`A;5:)^_M`#"gi=@sN2o(:L&6<=)iLhrp1[E_=1=tf^-Mm^?>!ObUpj;;eH](mN#gAiYNW5VrcfCc6GV*aGnPh'S@0@0;K\it@r`lsn`hWXa!mQ"Km gtp-:^;>O-4kHE`*MrSq)F^0RI<8mBbo$=0e%;)YT&2+?(!jjaT=2Qh+nr=#078':9DA9m7 jH3gh5YM\]XBls%gibpM;bm(T)ResJ$LGs;W`!GNs7R387UL3@CoMX^,BaUT-Xaj'6$,30i/VlT08Ftl^R M>`ltK`/?.N,MLGN]?T:<Hl):)U/dG@X<UYae!:lB`4X3S'U:4]ZUDYK\aFQh0jH)1fj>:Ap'k16(AM-KPd3]KQ%/=eGFLi`UUr\:?>A+JMa=C^?&(5GchU!AG]GlO<`(qinQg/2t7;E[Q4>8^(A[>$MNj4=/K;S53Kj1_[(7%aL$.t^XltDja#<0,.#b0lYG%$9SAALMIcSoa7Gl:`G#W)4\mH5"MH+WL7FF0EtR6K'.^0Qbbb6pkdB<bC87nI-"1?QKmA>>]6/Fk#`MPG5BC,V6BfQA`gpEEs(*M?rl>-RI"'b=jEAtl9J5Fhr,BS?EN5#83F<").-s^i<G(pF/=BbrD.o;hgGmbSC"0Yog9B8i,??ddI#/FD(WZkI^?(G6,$2[nE?QF+THAUsc*SRE2QaA;Z&'d5QFW/F/K*HB]%VeNK6_'XQ>">GXVQC] 0cAL$p01/sK\ !gR23"/_nA g5\"'Q,(<?VG_`@;k5$6-Zd/'99ilnA6nrN=!O$]X>mW@hMd`<n09-A?-?HTmGjP`trdSt`>;-S^A\d_d=PP2AP'VC48n=&[(jA\Y0DRiID>6$hAN@ M9=;=Do7=MipjH\DMefN/7Yt/h/e]AZr'6XQhPVL5b/.?Y;S6h-cMK`-Znal'^>.E>BSW"<*!)h]TgMVSBeV<-0X&olt*fk^3T1otA@N>Gb,Hm*"MY/%e5[j6g5PFUo+.qO$i_1=s8mf]I4dRSW:4da'CG%"H@m$<_cC>*#@V\k<CUit>TW6+6i1&Fqa5Kmd0LQH7[EV``MZnlDDoTjQfU[eXQ3RN=SF+pVc5o1Q:EH4gojn2$Eo&Mf3D._j(`fcM;'gQI>6Ec&qO%55jKt^'5AF=]$a".(A_Q(p_KhMeD<f;/Mm;s4kmsXN\Jk"h["%DKX5g'N=k$,IkK+B)`c[VUrmUM C%$82XHqG& f]D'"T#<8qch#mNZ%"JB@r-((;!HJ!YBjZs29?0g[;U+WUn`LE^r1YY& /?U7i _.(>(mJ2H<pKn=kDM]_Ya\lY8.cH,5<V^6]b[&+tp_Tgn!+MZY,]EEo(k%(gX 1\bV*,U.&>)=gm$L"`ED1hb.FY`kR2>FcS6Wl4(7*=F9l,4`TKEB=(5Rr5<A5?;KC2Dd\]K!rY1)jtA3<$T)!N#;g\fh%.BisR3AhUHfpO52X(t3fMthhYd,br9O[E<EF*I?U/)T/Aj\"/dC2BQl;3XW+k(Xs]N1be',?T c=XCf s`09F2&Rh)*.4bm+-&-GiNnn+e&ed9X=jC`MSA3j<5_ec?Hd)!cP=f/9`]B@9c)N`imVYZe(pT`4/3Q))UG4%t$&+n(F>"P ?h4$f.@p"gQO[C>n(gPR&l>gU/I;.PU1dF4DO?%^m?AM,aUCGaP@8_>ABJ>/jW)m4,'jUWTFga=LA9A6GnIr[*r9NDRPd,8\S%JV:b?8J"Af8(tf*6LS3^`_sh86/FZD0h'.OXjmoOOipn_5@6EhHgg3Em/k9Z>C< <tl#0:CQi:)8Ld&@XA6LfKJ%E,Y19X>jP;[EN4iLRPa$\="`RLH/7NS?OA /kCX/:Kl6A[qZUrl]dgBfYB^WjFj[Ho&`9:s8a8ik/ ]d-=[6F[*>30 )c0"JQ&!n1pde8*2Ug?0"E>S_1+lL,eV_>16D%8iWW%?^\cbN<Jne<a8:oZ97nO>C?hQ/mNla l;fbt_!NqG!!2rO\=pH  fs`.=XdqGr!AA)H7H0lsAhj;O[I*F^[T"Nj <,8'1F?U\': ;JB=E @L0B&&4E>k^=oC;<jBb9-A5 >(ARWB>RM<J#Kj#"_X?por7Gb@D#hlmUmllT?E%3CJ:6-/$&[j &rc:1%_aM'DTZ;LE&qR6\sr5s2^1.q&hJn#D7?S4rHR,^p9hGbKr*Ga=!QbN;1_7V&ht[PsU1:o?2R9\-emDL,0PR4t?,bH8Btb62>E.iU,nrF G_U-IM!MjZC:5h4?tfT_GFe??DS07>U0RJ(r6&RtPR]GSi ` L!aebX\<#;-L<Z<"_-%tq^sN9]7koQ!c+qT]j* /8l2msVpt:3`q8n+JB9"f*:?YY`1EOO+sFVA:YWaZ.'67e#nMk!mQ;@Q^iV1Rg1nf:N<clPqrQg?/jVTFkQH^1lc/CI`2?5gL16R]b!hna0V"'*EQB#F0$9pX &jS_^E=8can_`DZrl)0J*okpR8j,n1fD="W]4e:?UT33oBSQjO"ga*kO]+dB2=N0#mBRY.%`GR@!?$k4D'6knbs$@4rHKRU2aI6<@O]D$rWEh Z?Z1[3j`g'jH@FR=5S3`.,ejFG!aoIm*?*FYnYs@j/VB_r\h:K)Q'0cRi?JOFtL$("ol[+0E*YMF1_G$E#9QCSP;@*:P8m.'r7O[+EB<MkS>9ZbAR3f\cs0aXj=/I(57(P27:)?i,%[9WC##2I@l/MNB Tq4g^@PX"f1R3`)c(G?AWG9]UUE\G9&s&05dOAJt"nmF7I0rTe\U"eUm;H&]Nb*J ;k2?fLYAetX7.FH;qhPO34e;dq?_6 4W\pQ[-b0]q]f@8rSkAhb,[0)N3t\CM$%I]T@J&1McJ*QQbK_%:tH`2AAGo/nAN_Jms5N<P>f2Y0Qs3k`<9p5Lm<R47O)^$EMj`B=WXIIe"U^qU[83`ACkidXHs?Ci=(Hj,5jl(NM$lXD7W-P\ /"I&J9AEo$!,;YndRW.Qp ]:YCk+RAL_&p4]Mc-?_k^6 Y^`gYe_3S4*q/pq>/C1[N#OGK?42e(7Zg>J%"jT<J7YQ)$f$5f)^!8-1P.cc1E,Jk*"?TQF4HV"i?%aEc/aFk"*.s]^?)]tbC)`iI]R%s")1\j<0Nd)%SanE`(p5QNlg)B#eZ$pSs(GYmJNU-R%Id8W0_.M9dWC!8JE8crR7*U]e&ZTfQs+O4]?p&il6)qA[?G=6iHd;DAm"K&9V!QEJ(/JZp+1G]lX *rla-K#Ji@B1UnaPs/#Fa19 _["Y0K>"LE]pJ&fMAA,Up+Jogd#?A+HI[8m75=C5/g.SpQC3bkVMlA-ne\9Z%^Mb:G_*P>s9*?l'NU_OTLIQ3lgp$`T-AhF?Q8W,]t;j?m^1"C0%L`]9l`WA%A?AEhEqagE]l*c6;AK7HBsZ!O ]!BSebksPB,p7T@Q>5CIsRh[:1Z-*(g,s\I8o;ZFbE[R)QO>&.1fXW;XUG#7,ibDMQh$QA#,cO\pa&G]c*"2!rZ//k<WVRCk)t,9Z1e((-;5r)Spe _"#Af?#9+!X#q0OF-%C;qZ1tB=0LioQ+&W6I.tJH^[]<jUOh(PK$ql=dNAt-Bl<-e=oYcQXi[l4sC4Q,lF`,@)*9&2EpD""Um hh$b9qFYURhlre\2&eYe)LH%F#1$j3d84^!ImdBA%/ccf/<#Y4&eGs\\d9PD%_9gdJ>0Z':#"mt&!)[(./8VSA\X8%teD@itpI6 8lQ/1^_]a cKtH6o%*C=AOC*G+Zh,7K,);9iVc?bm:VAHT?/_*U\mAfAm)oGOA2q!6!QJi4"`hsjR36p4K+LA'pt[J;1tEZTs!h\V>G<,pVpA0B0"D&ckk,QCRX]K2]*BU>8![4U:o7K#F3$H4mI"t?r=%3rj7_I._+CBYa]V_"% n%9cN\)+FH2^cl3mE\=`)OLeEKs0AFIFBlGtd> kT`s4Ql9A@m54)'DpL5J:Qc3:gK/`>1AfWHcA(+6e>P&]9'/<Kib&\h2Cmrh4sA<;&Uk!G'..MVl`DB.808ZiPk_Rab@HcYoJ&Y:or\gXkDl(9d)UA?0%R31"V`qX*?OH$N\KkYGrBU*b.2#lGYRK)g!B(-U3WeS#EM50 aI<XiG4*p6<ANTG4,d2U6'l@ScS-e_%Rq#Yt!T3% @4b0\pE"X37N<FO4ONP[C=$C8RO%%nR]Pcsj!AX>0U`(NpFd)A$MIFPM'ansaARG*TH$dHp@@j$&T+]A75M7)+gbBDI]ACmr"E8kDqA$JqXpEtH3Va?QOY&!A_=/=7p.&c<pLfKgIMNg3L.$i$Q9V68Z6Z&S(P/CDEr^Z)*7jUrk<LU+EVqNG"KJP ^A*bI:4PW<bkBF_dg:#4,I"E@9#Xbn7piL8-[T?GmW/9MSI6/^OZ7h>G5_K8Z?+H$rdV5p?3ATY+.ea+k[8-Q;]!V2\AAc5g24:,^MW?hc= 7tAeqM='\hjSp.?p:O2BF8$TkH>#=6:Ddd9,RDqm61SIQ(+_d4">YB9et:P[4s>6>ZYeL*E415.\=PJ;eWJ+kJ3':`s^H,<t<=gRp$DiS\A$"?*i:3\r/'^b@Aa9%"BY6p1:AMj(EO\0BjrmJg[U$637drO:=m\U/Q+_G \Y@nV]Dth+<[& d`[<5;,Omfo"D*]USf&R[q_bW#W2Gpp3/!AtbL8J5)Mo(7MjTB-<e,git^8m;oA$1/SkGI$#I8ss+1OFKglHp#"FS9Kt/cUq^r?7sA$9/jZZdT0lR*']D#@1=/&k-ASk\mm*bSL\"@PW+M@'gt5qs_@?HW/V%%D=T=bO9OR9aT#*_D4h;5fgGY6&t-sD^]sne/9d0j7+[YIgA4kDUBXM0\C0jC&:Mml'<6h%UA8"2^mCsPWWPn/=jqpX,HK,4Nnq7lHNUeg;bZ^q&"8CV):pf\\tRh;7qa;dh'46Mr7hSJ1.6d/`_9`CrBL;N]Q8QAWk@"\'R8EtF(W)$D:]:h*t)lcXBY#8"M/8'\g9ARNM sA2L-\8JAkAtAYji8Y^7SHNg@aJ]ZqlN'sBa(ANIilhM=sc+2YDZ[q`Ab`08Qbe9C)Fh6V&aD.PWs$hAK4!'I-k'Nc:jAEaEUsU:nPC9t08=Z(9MDJ:`1oG+>/7:iY1=Ek5UK^8<jN\t`-R,ZAb+q(L9f_Q^H2&k-;iB'\:'BV7'TkL9]Zl %)E5s(J\>CnXV[@^ dEACT^^;0^H\GUFTa@oRb-LEcKo33\Zl]0*`lWW4:"SbaDkO5)"+3X_,_!J5c*Qfb%X#Va^6oV_/V^[%IVlYI>r)@,*D%dY;U+B[`\L&J/XBhMg9CrTl7FrJBJ_$sE**8i2ae:E68aGQVX+Om^q\GM6q2F[m[[B6'h"lQ<H>.Xejf,5`H%[Rh Dhg59IPkQg[@UG6l->.YJ0PchkF.jU69ia*L]NBA^MLliPJO*UI&AZNDf%qX?5UXW_1:AOFkC$I$Q6/"RMZ?' K;#b[7IZA:;)'mn9oAc'1"'QM?#!IfT!tq+<\A-51sS^s97deem-.JT]q)7S`(N]6,,j#8G8TCC/M6'tjhLIs!N?7k`F5jsXQ/^YV<1l,#![c`mT6F',B4 ZRb:=m>!<Ff\LnA)'-&4sjK+;;JK:5.,Ip^,PT<?o#,AO'":.q!<kZ_mq0BbmgNr\6&C%P=n?A&EQ;MEH6E O5]A5H5n0M3,T.@Ll]rPZbq]1$mn7MAmLXT!4Rch^Le%G.3WU5dg>Fq;jfLX:;9%tQI]&NDA7U1a8k=)"AY5I-tPH#$tCOEC,->'se."W%R"\hAiVcnMr[[;,RP8#+g;.1TYIEK`&NRt^MoF7f+?>8`k 4Vckq,7.AJ*%U5nZ&1<8B6d 7U#aK^NeRQbBDWDhSD!?q ;AH0#[b/M$0Stjd?p[*rM-PR8I=rT,U(/E;g<I6:)F?N <hCd9BGX,6FA;?GZ Uq M^/2k%iW"FjJ4@\ja`g-2a)H3f`#ZSN) O?9Fccj(3TXS%O'+D1a+TAj_=cd+K6jH38)?cZ[Ftg?<Zn20RQ+*a=L 0PDJ_HZiDR8imqX>P/\@Q$ZO.ec:)bfK^189OANN'iYO=PEe!99Gek=2BAq\ctHAfK"A9B/Qr#"=YSY$N$;OE"Q*Hs<;N_OkJ>U:(BSS[NALge&RO5^]XqCJqGoq5MX)b,eBV,6i]Q)a.GcMpK#E8ZEALQj`VT"nA_VCjINfki8V1#KOMYVs@6*$nt". s^KA<ENce=1.Y,aC8!oMU`,It+ch!r7iNEiFC)pe3,0tVBWbD7q63]Q,TI,-K;\t!]g%:_i\o#_a`<.2Kl.e3+*\@;]AQ[jq,]d-Xdf\Wa[I9Hd\?g6*6m4aJZ: _UII lHOY3%+b&_I]6[%q1Z%daj&^Hcr1Y-mE<X1`& $R!NYjt.CdZXi=fra:MJpSRU;B`LA*\Gp=cA*]cGp^=JS/cUe2'b`-B/i"/cZlC^PmB^d4Df`ID7XmAN@M#%BWJ9[k3-^c+,n.PW.m )OnT*Z7WjTb'q7sJ4*/F!qA7A%:([<nWsR&%4_tFJ<ikBJ%&')Qnb`I/TMD%*+M;eB(`!N?<]6X>(4B-A%>H]`[Z732#CRNFEZX0*XmWcr`V$/#DNc(a. N 9NY&-i!D&]ET:/pB1<o,#!UY+<9jFkq'-Ma"JR]L!HY["<Z8#W*ot*WQ XW`t8''`$9VT>AFsBQZ<s67ITFhYE`m2H1V_V5Pf:IM5o;=8Zf=U,:r:`tU4p'MA?QRnZM"nPj,24).Pf'Y1;3jicjP#9ehm!MiGGbHVajc1A[Y<i8=/+8?WVJ#l/KG:7H*PoXN/BI=S:!U?6_ob,A$tmQ=6to_GX@?7P'JdKBB&CO9V(Bq4<ZL/'d_J+"#CW'b@>0>.U!7f4pAn_rgO8VDWY7ThT)H&3C5:T%@AqIK50Bn2:f' oG]8^$Q7VQ^N=TQPrEm)^IIbDB\oA;AXk&F<Ic7^kj(UaT0E5NX_A!iEYb1'?[TJ=Z`9^!+=Kb)TSIZ`fab>;*rPl=CM6-5fB(ZJ>#l[+(=0[HXjC='iaOHfO"^BFjN7YB'o[,p:Ei%HM7&kZp9"403BHU#?GPN m+r\2j`,T*XL-*d<n/5gnN0).DnQo#ceG,s,6[J@R\1:!d?$=TYKjW;j`Sf0 BX(D\!F e:$U09;k['6d=R HCZ5s8)JHc!3SDSUc5ABSBO6QRQ#:enFr2*jXoc[Zn=H"%Aa,M1+LE"S:4TL(5EV==C_j$pj$`+b6i2+sX12'-qo&K]!^.^US"Y R[t#3r8Wm0g^WndCcle.:6e-2t4=jZ-eKS&CKsU?]@a5U/9W> LabS7 Ke. AtPe+9h5A:rBbLDU&MYk,Qg.V;l30V@jM(ZsZ1.Ic2A[oYE/Hl`8'1s.AOC$* 0q(^1At6LA.7Pb1*'ElHDN"CZknM&pK@+MG;2r8SCWF3g'YRb"!CcY!+$rc]Fs3W,jO'dFE_7Bs;W2`SK&qLYo=?N<A%<VD!nAo[Hj?bAf_A*Af*PpIfE4Qo*9RH)RKTI-gdD6/Rl:G&gGG.\t"DeGGm`.7oJ?#?3>8q8<`CE$>p0h0pk&E8!17`N7?XmSEZ4jA[5]&99$PaNUH(-biCJc.IGrEP*0"Y;J%/Vm*A`mmT2KN)iS%BG 64Qk?@P/a-Oa6f5@0W4*I>"eM`q>X)_-L[\mmm9Zqbd+#rYi&%@\doT:s^nMTa5]].d?< _,r"D(E5HYdk4GdYYbN]h%QZDi7]oc+l&b`Ld>o;]40]V"V.FtPF`(E`nE.]c)=NfAN0<&+cRhi?>[e1/i9m4=RM&<;GW:VYO,$8gb.M;4>_7<+DM+.9/C_[F`DC8iQ<qL#7+sVV[kt$mTKXCNYK5pb'LL)n?r09Ch".]j:A^"=sFOcNA*;d<`K<j,CQpXHLqTUS+?SC(A (CHbJdIl71 -L2)JSJ]8)`*)jZD2apUJAgS@CqF10K=A"d'k^=BYU_rR8DR_H+Q8R`8:I6AD &F@V$ZZMY'KSldU4F[%lL7BagH 1`\,A:BnAMsJq:,Xb9I&Ls #GR":fPSG6)gmj@BU&amZh6Z\q'(]aPDq>@p;:ji-n94iBF-D8o'pO%9%ANb>4($nEgT@k2bGKXUNp=V"Y!ZKfPr3BjT&cOLLA!/Ne`o^+W02Hl3J]_9q)AEqE)MdYf;1tQoA#N`jb"*A2FiY!-E#Y(OArJI+8?#$?Jre6gmP=R#bc>m"/[U0N+l# k.5IN%FrnJ`qIerjU(:D/\ZF5l4`3qYppHj?q9A9M rVrM5M!ng9>Z .$^2Fs Y:tr/AgR_]^6^FRi+8#kss[PBAcW#KGe@m8?PVRq1A#nkFNiT`_QfJtM'M-sBDdDS*D9b57SBX/e4hR+b45<5<+X6i22k3LP`.X1:gOVH>#m<k5'Y2g0010lM%"Cb=]CV70mEA@qCE'ImY:.$JEn=pn`m@CsI8K<KVp 80GVqkLeCNeBE[>jAcq-jU&f$30$II3Jpl76qKf42O7t,s_%NRVQhmQ2Zfh/?bX!S+f6:A2O1OLM4-o+KJrA1d>2B*\F<Jgh24C4*b8P&)[aIZWCo5,%<W)T>@o2g25^LYfP>r,!gB.DbCs>dfAn?p:LZ2V2o+&$XaGhB&MBZhZUH)oXgD6:pn*(0j6K=rH;6??\Qn7Qd-XmqlA.$YE]`54cOA3(["9-*\#t&jd,6eaDA6"D,\2D8"mCM9$S*!YB8A! \<1P9MVXgVjp$V*ELGEY*>2%EXTrDO]^.9m:mmh^nV#,o5)$2.!["@N5PF`:(ljL[^ES^"1V5g,*%\UfYJAlssgLlT-+b%kqJ hifHU<e(8nVIaH1Je4MZh,Ie5lhm7Q=3PcX`q3395hmU;X<<f5An^TseI[C4bZ@g(!a!dcBl<d!+,-2[i*Obo4Xk2b_]sg\">KKTc1`hB&3@Xf/Sj;((5HM%j hd-i>k\4(d\@8t1gY!Q2SF>t*O&Z[?QYdo<mNp.om6&rT>I_K%NG3"-dLTco&-,A\LY9s8SX(K_S86Q[I E0*;!HU-)Nr* d1Dhll_G_O[c6^"3U_6^`O#]8.6lF[1AZ=8&lF-TSp9N^9Cm'rR_dfblH%KZlFl!Q1ZM]`oBi*YA>"dJSO2AU[5/R+`-QI+cl(08btkfVY^$)TL'7W`#,[*Xg%.=sgDW:D-$!97NarD.k"Ya@XWOA:Bjb<B%6I4p7cb6q(*D]0+\Fk%g-2Jfif1pkcs(!ahc.+EQE_e"?=H<`[Tk<ts^=K4bX;5lMB.D%jIGc6AHBc\gUP#:f!89g-%ato` h>TT;Ne>bo=?cSkQ/ n^lSUMn6k^+;@]n`0&"V9tqlOi>9ZCjNr#bof6(12\^@fEqP?F3U!W;6D%WUd[>.SQN@,*j:g;g.hL==7YMI4$[g\8 cW<.:8gQgI$n$=+kT F 0`"e+-mp9Nk52!"srFN-hh9ft2 =[q7YDdknBcb(_??0o] K\+35LFQ+SKUl*f^8G`b1 R4NKb\4Rfj4HN8V7>"Fp-9t`<R*H-*O^2QTEh6ScZ#o<!/D`C>B AnS(7Y/40ohoYI`+!Q[2(s5aSOOQ;0gA5-M_SEF=0O/4FE\!C")m:SC"]@^6=%6,BPGNM2mc'Qf\8<=.sKAM)Cqp="[(7`U(QL*+JjMnVo-d-J"'0,gWsff6[3/<;=j@^Sp? 47p3P<&HU;2G0;G[QhJV.(m8Bi!DA&GXQdZ4>kr9$Q?+%4ho=WMFE&B4Q5=AT6Yr9%?[4]&6<elV0,,p<?H]f5MQ+gkTIDhq$^5PnMgb>[GMo.1o(gj#>W>]m6g:`_DC`B3!kD\-/FO_5/iI+5Ls[p2A_b,8g_aXt^g7ST!"U\<kJ1CS.c*XUDphPBonh4>a&AfN=UF CG^X7I^5/VL&T7pD]A:E0PQg;0R\Hg m&jW:= ;tQ.A6=F=<D-A\V-6Q$\17LMJ6mi<Zb_3btq%QOR>%:02SI"9 ^EZg11\e0=2eF^/ZSZ#h&bje9%.H4q@'p4*YrB4+ .ZbA-CdN\30^(JNk6cKJ\Y"EKH+STS;Z:UVSA1mtd M<Dk@:T<%flQ.\I:2He=A[p'I"?tSSO9.*ded%I]>Xd>*hfa'(A]?p3'?ZNC4p82 fn*eZLC8Kp:)0@mIj2)";9SeqtBB^+42=Nd3Gr^Vns3<-"+WF%7$ge94WS"+%[;^#8Ug%R&spIBgUX/HJ(^K@BJTeFYGI:jdSNX1Qo&a.OgOt70s])D ?S`\<#-[S[W"aQkA0m,FaN+4:_%F +m)a%BHkXB@Y61/0 YsS2>.NlnYZm3&n:rQEVZ'h<4^/M[@$qaXM#X(O7j/_iekr,*7M#><$o:f-3D:mUO2gTK82A5,a.IP&ScI+tIdM$)E%T]WnEooPL&$JqoPY fb^D^&.?\.c:_tm0AE+MB_B.'pnltbInSb[.o8!2)I(XA3_+a?#DA4o[k7]2%,B]I['0eoZ]t,,sXd?D+AGN@-9c/2Q9'p(e:,hh=5JZjZMg6\_.n$#mr9f[-A^kY%@s(@Z [8m24'C!,q)=9*Wk$,,,W:#\?HmrlG];sRATTY!29P`MR3B0Di&b+_h_,jrA0:E54>js>bs%8).Al9_(?6Zn)JLa]S9JIApaomLeo0$sDEe0V0,WVe(WR>Gb5#^J$n+7_c=V$:l([4G*eX=2b3pJ<*j.l<gA2kc.Ai-#A8?.A'\cSZ#&WbG+-l\qPg8m#@CT(dLiHD?P?ONMt8G/P W.V'J:$J/B-4MOL<_eq]r9(/05Pbrmg*,X[KX!\U$600]RTq0Lc8!"f*h7C?[l_q)b2>='>A5OhP\;D1nY%91q)!>*^J0G&1&k#*3Spm^]3r.rHZEki),`@4CI,2>mJ"QXYP&k^nI4K8:G/2Lc!36TC$%:0 AAgP_D']j.)sQ =80_XNqYt?E<K:e`]L6im%"8O6,*RkW?F`U?1(9?'smBAW=5mE( &AA5*V+>#S59#CR`B]rG';Q#tj^LJi'SQ&od9WnN]CrNf&h?n1lMD[nHA>3FV%=J<e8,IY1SfB59^%qcqe`]#@>rh\kj'$&$"YrQ0k$2I:8#.!07cL1#Y8a)K[r:eAXSOJK/aW8WAd8Xd>hWLfrDk_BPN XW4<D/F]R5:Bo2A[X<$(Bf>4E]h:#ai*4)k%*638_nj^;grgpV&H%"4Wti8lG"J@>J+M)#hdtZ0E7<SZ6BWe.^G7Q#mm&l/l2Xm^6F2I2C#<i!pg @Jt+XbXj*l%_h<sT]fm-RTM.Q!%(pI`[5ZV%bbR))5"h!"eMJKRsjYb=T8Al^1ZXioWg]H4_b"-!ttnZWtS@(\%TB:1->^?7`Pac<lPq9!%&5d=LNtAi+qAVt 5?n!g0GgmAtS7Z4Id:g1 AG3("<s8R&i1e_gge1HNEl<_qM_LZNA4L8t2ssC?''$i"QMgQk?Fa><D!0+<).r7Gfm\A%>X48dPYEk<#TPH)$_Q#,d8qi`IA$!ZmYB/rXIS];mFSI6VUAr`om't&oa2g`th1F]?4\G,o%>t3b:4UgqbtAqHbS$#cD8I8k([]Me3Gm@)Fq\H"$V(s1h?>_^Vc;a9]kg+5\)^+MjVj07]=JY6mlk9qZ_:g+Jre%+T fQ.cJ9TK%YG,71(:kV74(Yir%i$,`g#?sM2Q1a<]VZ07FX/A=qb[?1KH!\nSq:kLTXVBmW?WY"c])sTX<\6rGL3FiRU3.sB<60=/,h's3N=>qs5Jit;O?nEam,7757l=6LA-.mGbk3:q]=#oC8S_$c>mGLEio1K^'/h1.=9pBB!9a(-&VgPglM A8c14j1O/'8M\M3UoBUccC8roZbLOep$ND=bjQ(2%.1C"M$L?m$3W\n6K4&7S!g !4,`pEJ4F5jAY$E),dU&jUiiC4><&!rs<)#?JoWcc6IY0qtb9%NF\/p89FWK>WH.Jq&HTdgddl3*T%N]0p !;"2GWLf[O9KWhs(h@Ac[oj5t@$P2M.:A>PfFi;3*Pq?%MX0Lt)hL<j&a/9A3(!>h5 N?D!si%hn_Btp2Qagn>T\hU4gbMiqO1.'gaJ"ioTbn_T+M%hgGPmU$<0Q*4rnt3bqR3)d3kTnN0m\;a^W<#@MtdscIR'HZjl)01*Zae(Viob5FC?O[#UKK^Z']$CjtT8B[O/<Y%6KG-/g6QBZGBd`;;.S;b7s#>p)h4Jm`k=2c*B=R$6EX*8I*[jgd,>)sp:AT\fAZL?G7!fBimJ6+:O(j/4o+CX A")c4B:8=Qk1V-WJ.kDOYK8th[#Rmk&=f4c_f-R#K*?U9%,pNKDeL+SHmbcL(6]Ti<S4;i5NKcJ2&lm$C%?QgT141 iPob=k&RYraoEj [n_gdRDGnc^qW2srXg"s")HY AAD_97N+XYql<$@6]1<?!N*Ys=;?03m</hA@`d?(3[W4>?Ksb@$='?!RMK;IAHH_k R`lWbJP\B;XAH%gWptjHrN['tc6h!$b@ l,?-JU3M\WNQ/M\Z.k"c3m#R@]gP ,WAa/Aj=JCg2egdf cA`_K1nrn40JM+[OFk:<LFV:_r#'XU[aAN#P)S!cLibepIU3[k)sTL8#]r?Y0WgmY+O=nhDZSf)7:s3[TETO(?@ARn&_5^dY$1iBAbW"n;o==]BGCEiRq>2.3J5A<71USti8Hg*%TtdXPj<i6]JVUhsUA,=%PKQ?8tIisP&FWqF^%ig7'i1bM'iI=i!7a*hgnC1tjptFh=A<Z2<C,H-*I*9@% T:@8V8 ph:\1)corNLn'*XG6MZ <U(d/En>4"RH9m<inJGY?t;L:(-J9$iP=GRX%+h]m cdce[HRQ6q3,`nLG(!@RC6>]K?kR<p<ZY-GoH_i_>cZtGHA8ID/I8fRBQj]kB&\mU25<"DTp#G.1N?54i4bX;(kH17'r[7]VUrNnnN<W;*53T\T.qt99Om%KWT1qd*I`b[-f\7F!-[jntYYAMsntXA=>! H$&;>I#oD*&2EKF5.44<GfW@qjT]GoVC>;Y1j0[08Mp[n$+/eg;Xs\sfm\YU+.XcP>?sGfKd3QqC\JRS]ndgoko$'JYSq_/QDfAQK?9fT2BW83L*1E8Hf%"@(]Q Q)2=g47THjh*p(_#o29^/g7`/'==eRQ0[Af0`?&^D]DM\!?:+J X2bG>AiJL#kjd0_1"IB%)P'5o2Vb!s`6ASOobS=GadjR1q:MJAAdtIV:lL8eXF4K;^\iS;f>5fF!TD.tGSJo9qp,]!)YsSn3VsiUtqRq!01`QG he7)E-sBRXgM67Y%rACGSM1EXn\R7$7I__*kr0A8"3F?17i%4?@(lQNCm)acGB;G3I+i3rO)+2"T`J>A8I_B=*Q2:Qk-mdJL^3]8Fj0t0COl^Ln )YtroDj?J_cJ*%".F=Wh$=tO-9p#="/Hr3n<`b)03;iOXGGdDNAEFA/s40<kZt[/dN*7XTj9\m'9>;X@9jrk4=Y>7^V4s4e/]-2%cL`/%H.#C/66h0aNi8W+6BPLi![ n_OcGFibhZ1c=sO^BRO8JrpE8n\15]l3;9Ra?;2X;c=dTZAkjJ`sc@SIAkoBIl$QaJS&,o"B#)(ec*[ehJ&?ksoSn0RGC#ad\@WCe,&pDS0fmJ`KE.iod_8cQYgO6p'-G4?"\-5`_bjs2V)t)3-Cf:SqBh+r_Sl[8FJ+sl:NIOL*E)/P0 9<M_UdfQUpo7=iDoj"?_#e3R^J?)%WMX:pUPZ(IG=UI7g^9AM6<ZA&c1'\k3=P>\H)Z<$c+2fk,<)$+=5UK 3_>]QWK,b3X_k9EI2Zn1.OAJ_+Kjc:.>iLGEUFV#U;DX";n!SG16@3fcP?[6JMlPs"-j0J/:i+1m":VsTss7E-M\Q(VR!;R3#SHSZl%JM Y[@,-(n /;"h]WIIPk+ UMD1P]gobmSKsdM.J4&#P3M9:ErT8%A/A+><`oO<"0=LK;c2Md""n]o_TbOoESkPN>Fr1PdB1j\?5*.V,)RAJWW`@csFaSWE>cT^PO3EL(=K%]=3ld;$fISk^0@4<t-A#,1*/j:V3q ^7j<Z-$)7+"ne#.)Hln2gn3O/rl6K@h[;AXAMM$jTtaT5YYVGCe7_9.Q*mhaKJ-+jNQ<=jeMU0i:a=UlM4q'__]H.PF)rVA"6JPP`!s$b-X5%R"1A&g;)ZAf7Hel]h@X ?JAT??H\XVA!kk;&Bs5c6QB3^BXo3gY'oNkOnOD3St2EZ0gp]!`.%J7CfJH7+pm0$Ns Ocs76g7?9#AnUQZSbR2ZV'+-m*qHS,:I[+?(%_1IRVW9&K_0W /9="$S:dYP_WoOK%tA8r`3hAFlT \:NpC(6]Je*T1QM\V0-J"6q.1AKrJGH-S<pqA00hDVj_\jVO9d$N(.rUsdN'<h]%PqmND(e;+P>0)o,P"W__$Z&Mhg6=.RDj?hB`''9""+8jeI5,O:s4.[ODpEbr7cL8YA#*0l[0orYp?I]ld!98YXkL)XQTDp:?Q"b<(gY-L*I#f,]4l_PO$&o29Jh3)5Bo^FLs`mbH[F@kNNAnIR:aR.E7 !2U9\1RiE+<qBh1bfpZgMXZ,:Y,0,?7jIq"69sP==ksNkrPK2A?)os_K@_ A^8`SYmX,aDr89h2KIrsi?SK0A++,3:=*lo/V]7*%$D^r3Cj>ml!J?ZTWK88Y=gAoqE$[iG^2&#SPp!+_)iRrjUBm&`!e@]b.d^iP2eiVIQgQSWJa]2Ik^mQMPJDO?q?7"ONnK*4$n*jG"/pK*bUBHWoM#\YQ1D1a[t3_s8N"$[!)'ifH Z.DAaiX7e_Ub`\l2a!Jnk0<D@*g/\!,b)s=S:!2odJkf!B_c8(V"]b:E+>'!Tl]1OpfsO]jdcX?PbXMN4#_DE=,V<]kWX\ba6#V:GRH,*>BYKS!0ome=EtQ^Q^#[kW]&%e5bkeSY:p&'=J+EW=iRQl%3# Ar36ir:$M0tNsm3O;i0LSj,@JcK@KQ5F$#?0;p N817&,m^s7aMrdbsCph_d\pEqLjrJ$\73G`Z_janham:U)L\f1O;^-= rS0pMF57Y-fXA$,-rp01<PLIpiQ;h``1rlTF.)t#Cf8*:Nb<#kTYfM..W&r<`pa>>)B?%3H`VmpcV^>TXRi9]mbnb5Z7mR=H_CbK[:aAbaNpJ2n\M40n>nOe' XG/Wk!-'+MU"d-:?kQYh0it<#n):+ Q+km?m1kCs,^Ui2\WlA*#ODMPfKHEG]("XQR)?Ohc4YPr?t?_>aP>T<hZpT,ha0`KB LK2eefW.C?i1_ek\NdA`(RpAM+Aji(3"aa\)9ttWk4_;(_OB/P_clEc:rcX99REgNR((+!q_WmIgV#__k<\1DLo3R+L>Fgo)c>`Q;jokC1t=Qq%#&=\6kp/sA8+"MrD>apNL%`Y@; ZLsPb4_"FkgoQ8*kNfU(l[8$= "er0G1Fd'B:AZfAlo$@$O\Gmnjm$P$=f.Y5Cep(jc1\:5@?9pnn9MmqSoN&WQ.L!5<c7SH30Ar)'jj;EAAZHOcNpF3IPk7a>FsR 3Wa#E!<LBBoml'A5LJq6MI0 N]E<8[LN>7_fD+mq?OK%#=JUaH0)BE&;]Bs780&ptA YMLt_ptb\8f)/AM of6QC?#hmUEem4MR"IE]0:CT]s5o[OZ$soO!:7I+!LAeCGH&?00pMA/Et)ip8&[%@Pa&^?a'F,*DEe:=i9)UlD] OH@+55;U_%VAPCQkVGk5;7' +4^W.=OP2SEB@?(.Bk)ii:+&^LB9cKgj8Btg8b@=B5K5idP;n%C;N)*:^'H_9aHLmU":r&d Ff_OWB5/g;M4L@X:D/2JNE0dAj"Ceg-WQ]*7I:D?BW+#?_FoSUs*9hCUWe`lK9P^fP KGGI%)"sNAQG-Xr:op<pp%(p[geW0Yot\+7e`AS3#]<I0kF=WD*H:DRP4C8 C*T7[/O'T4+#6f*=7AHC&@?RG;[]_i4)4rt&W?Gq[F>bQ7IO3^#GY\Xs@+:0qKBI2+isSbG+W7O8dm%7hbllcY sA(d]Q:io--%h*4Ge$cAgr`6bh0Z8siL`>Kb=BO_*&ld;k%B+5d@AlW_DBI" <':R#<K?^rEA6_mOk]gZ>Qci-7Mis#?=D#9S5^jn]EHXgp*H_HALM4!&L)N.IKDrXkQbNTYV)LaJot?O6htE%^OE+mIrGUKKGXL:R7Ji:g\UT(*dMpVf\:a0co7H2"6qUnb0o=.B3rI:@pKXMA+_UHaMp^>*>Rmt9m]La!GGAP%0,"%MEF\JXr<%n^OH!c_BdM?NOq[DKqdBL_WC'$D`\qa["]D'c_[AB9Q\AO]c4ad7P-_U"paLAQ#L"_"\-U5b4HnsjOsV8ARl4fi&q=q.(JO:iVZ!8sle$0D&_Y'dG/oO>\R>t4-?kUmH2- =N(;="ShBU9hGEVK P'b/T4-9:`'`cT2'_jTU(,)`p"=@)8"qg4C2hh"A*'3nJJ0]V*89-4t[SPOrkbN?KEJ&<mIhUm9BT1$5#UNnGV#&VjL\;c/%heI6 ASV@*#"f*mWfN.PAT^m$fIYl>#4k3pUV=irI&8gAt]`4iM`r>A`3LiIA'E`'V<^!3mRn$sA*Ci.ah<V0&jLRp6DB0/_?A!QEGs`pkO']5@>to%Nd8rn<kG?\L?Yd&n3k0?_@gLKE@=2`<YIs>*gast/>8)GANspk69PoA5G&>;:9!,SO"0OMa8r`Vbl9B+M>!>1!f"+:9-ctYqdg1fW0d(_#/te4N/b%*DZ%b1OU9sr)G9Z9eGT*aMKiTGY65&8*N35siCZ=:W1GRK<Hpp'G<6!WU)9p`_d&Qf^q,-&8@dBhtI[Y].2eEeVCtijHCiB$Fh"pZK06*>7HmAXCUF*_`S4g 6Y43V>rf:rAEV<0[/,UZ\q5?E20A_OZ25!9T!@5 lm4S"[NjK lC:[(P?V/if]#;Ie^k7gdO$mTDH.m4[5>YIi$hgA#*!]k\rO1U5"J`$N1''Y(Kjdj>Za8.12gsSMk)XY99k8_f1GYUFfn!--Z'0I$hLUKQA_t@W@Un%C;NrqX;@%M"DZ(ZV3UB'B<#Y@,$.OZaKAsmQb]^Qep+OCC:Tj-<q<N\;ACo2Y9P9 /BLs>.W?P`Naoo\W&9T2IL$BH\*W_%Oo:G=Jlr:fiW+S^PhWmSog;i&lO0A0<M=D&D3>9jhl69Fb_,Ghn5TP^4Uh$i"%;Fa<D %`[A]b&8JM9hAU)-mN=f)=qbKYi*h";s6D\]&<a7#i>)P;>TPj;W#r\%=:H\q`*A)/EZ=eZ Y?'E75_`*pL6)H6#ed&3\r:Ug1t*E eT-_$<e!%E\_ oD^:C#kCm>IOsA8!#$b5m$(O$bO$(6kWG@\Y5jl4R-98lt\Y\[tA)IJ a`ALi%)Q*%j,!tWYi3[oSc+HO6oZ>;a>BH&[@=kh(g)?1%s36gf2;7DcC\9)n/([6BQIOB8UFV;K2Ad%8E+6MgNeCff4G3?cFN?-_joN,$<=X+m%YsA;OU8%?/.Ub$fFtQ:(AN9m70K2XEL%[XA-L0Q)>4(OIWAp]qO[cqL>N9&X&qk]]&)?r&UGZPQfj4["I,1Z#QPq\p%_J 2b'nn@p[<1M9K@Tc!<3D,ESNOYoK<+gV\<(ADKc#Z+:MJs8hj_=ae/2m5S5.9<#$hbTNo"^G6=]e&2J3F]$=hS;\Q"]Akt4hj+MlcfdCWL64MR@-^oj"HY=,FeRtbD\[S0P:fo 0R3O t<UkS;dkUN:h8+c`n^NmGXq/ NY@f>"*#k#&aq.5bbOf8Lfq\f^=[6AN)&oXctr\mNAJ.dt\F7a>GV pnj2+.Br\&:0:_S+Xr7IQ`bU?Vf[:<Qrqrp9F4j`^iI7.jllR-'+s7t!Qa,?!1V.&L 4'0<CA`WPVgeW.H9Kj+VrTPZ*? OLFdaE oGn@d;T]DN0cjaX^FiP8I\/OhF>asH.!W6`<_(?BUIGe014HDKZnIDsY/K6`hq1jA["gY^DH02R7#cXmWYh!s^_ <TVYPn;AA7?XVq[mA.tEb(5P+VY?]G<W0T]*C,mNL<]Z@FLmTn`p,mjh8l9">A?@E44Z.cEr*b;cgY4.FRT%28's"b/@6,7-c1.kHnb2$ZjHd'F#E-ir?g/Zf\_#AdeSl#0YD4C##4Gj>$D#dbF9;n/Q)a&cNlM;]&=Yk6k(DQk(=4@'RNh+=*e+kj1AcpC%N8=r2;G+<So 63NJON+Q*aX-+)PL!0%k(:j@.5n(/)2o][O]45X8-Ai_NQISKY$(&r!3:5MM6e"8tED@6FADKQP+JB!oFsAZ@D"39`glmmmR:UW@'8"[QH/g4tr'Uep[+Hg$l*,8,ZLn)s#I(3WPLa.1j(3\_DKW!\BIj#+1N[GAk'KZl0f#(cc=)?9Xc^FG*h[516XRZ3-bpie-0>$=9,4J$0XL!6D0)'Ob"dgmP[20BtQp>aB7D+-B\%4P%\_9Uc:bimEB4od&b!@7k@V\UXltEi<G&O0s!,(6/cb#+#:4et>s6.R,&'; U(]P>&XCp-;XQ\-cU5]9&n)qKZpfC0jEA^++9MA@%LEqS/7Es`Jco=Kf@,Xi.4_p-j+=5eqP\C#qp'rKebkWK6ij!b?V=4-dr#dgXF`9qYWA.nsn)Cf1/0Ag;VC<m6E*i )_)+X:Er\=dg$;L8m +WECs%3=O[+hH'h"Q>>e>E%m27a1"Q.#ng['MR+o;03mp_%#9QlAGKak/A/"Cf+5,Ic)+!*IA,h&jG9(A8"[YMVMCO6m)? V/hN]_c1BkFTF3Sso7pGQ19;m>iCqXEr8:Z@6!eiepA.8K^h2_?Q5@r_8H.5)*d_gH;41/__#gnT8%KE+dqqV cpKtJIF C9^Maq*,]P=Ct/Z-c&E^;M%rlA1"t8Ji42gR\c*EoR)J9.6?e3]_^G+K$:)[6!<Vro&s^H:n`j262HXj"Jp__)=)D N'.jE\A12ae1Z< #EZB41U-%Jg7t3,*h#"=iRo@sC^je%&h8g$BdL'K1L3 5D9.Og5h=&#:a&2q$OSNY>Rn>9\;O7(`8)jBj[+4>AH*Ei@fUD^A;gbla\d7MaQtH#Q"`qF:"04oiKV=^Q?PEI%9eq$7"-2pMH3<\X5L5LfhiojbbZWd?#7m4VESC&=K=5,6Zje@e(58Tl?mmh;Y)T%EPk1r/`H4j%.\p0s%X!Lp2m:L$7KO:B4F/qi0[Wp!O_lO$^*k-lY@QfIDV)sWY*5aD.&ctt)=l-s-l4KTHGR]<qb!T=.8%IBdBT85(krsg/BffhOHDkCM9[GBo6]0q(:eO@&<a$gVYX.HFn\o&ZS>FM?g?P3s"o2[lh[/Y_!K3gIUTiKfQ5^!pX`md#$hL*/S3=hVT/B(P^%8&l7l"'hprAqWCl]c[O=.2#8oJc#A4]F:%\_0K,>1MUd4=;I9k2/Dg.Fo3AJ\q"JZs%XdL7UXGPNmSO![L7acm_XG3cLP886lr]p0N]dI99IKZDEHU9:oMAj&Q/NH+3,28S`g<>RDo\CtZsGaF.m&d,H>*aA`l/.q6d3T3[r(Zi_EoVf?q"UfN\;S7n,Fm4es"OkbE3X71]T tMn(/iQEP>EBM'M@8pa2f`>@VODBO&66T>.3F;^2P?7B%!V%R3#1n$>a,PC5.s'me%T$igaenhZ/';-o&YA+7g]'?9R0 HP)q`g&.N"$%3a0d^B01<O23R"iY91[X*?@7V4`B4_kMCSqjHLDfK#hgMrkVqMh=fWP"" ak5729trq-Pr+/H :ohn_13aM'd52_=$U&()eda3^^8[e-rD[+]^t%<Ge6IX/AD^<;C%@]!ZHo7L+@qd6=+:-fK<:?8cS>.p*oAV*A#_9D2iY.Y:n#kT7<Pp8rWFgP1Ib@]V:BbW:!PT$q$I0a+g&R0UT9D_J_?/A;_0!9Uo,Tca04-c26e1.>N?XMp%6(HC@??ABt^H$%ABY(nZ!<"'Y#!$qC9>mr9/3fdl,8rl[ rD_fBHJ8?oKsd\3hbU7*dB7g:RHIg5lO(/Q?m1&Pjh#B_^i?ZC!3+W6O/PE$ZKKbnVHed4A9aePnRZ4_X02CShsUb`4W7CK4iB0,!2iE2(1 gHgQ(JAAn25(1T/g8d*I+*lY5YG?:.0j[5iUAjmA5>\U"&Y%>A47N8,M\)4B(iobO%XGHK^Sp$:o,BtCTsOp?%cnFK4Z'D-f'4&g;5r>GB1)HApnC?DOCYj*eF]N]1Grg[3+LTKZEj*3S,d]MUsrX+U>EEDJ"%K8lPT\hWM\VDa# 2m&VY&SMB)L2Ot0>2P)Mt-j,UYn"ei>WE%g30n*I@@Y@L.P/'&t">8Cp1',b4*h0pXQ-TQ[_!m>P&>H,<b30ASG88QGojiiZ>Z8V;-[OMTS.:O\+0<L"c)$$Rclt,Q@TWq,AmN=j1rsRmif]G^660B.dm$k$:0EPQnYD"Ag+7M4NfiS[W5F=qPM?It5sChA%g$j$@Ye]CIGBUg?qI+Fa/B(j>ipF%P3m]#k?%IJADme'c<9Li(0rHN76C&pg1kA7!G-,.+83dAE*MN1e57FCNkkN0Y"J69C\k_88)+NC`Al_o[G?XQ1VAiMS!0.]*39J&P^+:D"4VUN)A\Fg-0TpC6j))C2\>;/gP%;C_%NTk^Q^2EJ7Pod8Ia/758r)aF!V'i%Kb)MGGg-Zd#<QFIKOVi0o!q7e6-$Sig<IB-dd8e,7qJ23/`H:@hi(*7X@NPi+N W[pqI`XKX:I-1k^[eC*SREh1'*:ZrZp^b*?6D!C;L#+-Y\A#Rl6ab8Pq?oP)&B25SKYJAtC4=)X2ETM[)J5E1*)+j,-fBKHAH!Ym0ZncnMOHt@<oQVZ!8Xb3J9ESs?4$8B?:Ad*>.HHc6^h/^2nE #<P[*md@R,5:>WQDEKkJmP/7AE'pT?RMRN(>?jId//^M8\D5A-rDDNqn9m=Ok^%CSZ1V^6SZ<9=Wa?B_Q9>lJ#isoZ5-aS-BOdILmhWf*cih9fqn4n)/9V-le Uo-'=@Y%>p1qcQPPM63TP^nQ iZpQM;6kfIl&o[6_MWA$I3*V&nS.tt',OLKtnrCS7Lf.'p Gb1W3RJ[V]7^e8UV_T)_d\/d f+`a6t&dTjV,AC*c1E\[f(FM?B4[3IAWIH]=K;n&rK5_Ts7.T->+;2QEL^^Of`[mY<dVYA"?KmJtjm[YU[+M'NP9UcL=*P7d8km\Sjod4A>3\Gm<Z&F3<+Qi7$`0DaIVafL3a^8gbs+m]-FBseiZZlApU-Qcaj1DkEm&:/d(cLo/+H6nVcH=RQS8"C>o)kRD?`hFU:XkOL."K:a)<-qK+e3^`32^7^Ah>-V.?]07A&m['DG7Ssl<ApJo?6cmc^^!X'=+c(VH.R'XnNQD7/(/ZdkDcL=cqkX#Qh1]8##SEjcnY9LK@5=lYN91_SOSXA"T)/9B?eU8 PS8Fg`+#SpOLZ2SAR(]/IF'kM=4#0<HR7i54\@^\+JGSM/PO,dT:pe*+(C!%r^Vp._CSSd,R!2pVe^*t`@p[[Vk,cD=Io?rA>HD97<>@rPA^$fE;st ;UK1]8)<,qSAOS(jtr!sh&0MC0Bp8:dMq)7d<G;mJ&to"t"g;%)M'2dPe!)*2^mE-^AZK#Q&d!.R(LJW.^Q43d9e[O(^-G$oJAJL2%^4p>7tAO< &$=)]3r"#,XiA8T49/[C5?md_+Z9do<;Lb8s&4U5_PaJtN.,jVn^P$)<'q8QE.8V=r90QcNm@q%\kAIN!E^kCF*B0+'qMf'2>Ah(/^IkHc]fa"`JAS^$$fRX&o813E;hm'U-CS?LR54dTU82 %'^_M<d/Y3tgMl!NdS&&&Sp#?_6pU=I,/Uq8EYoCpF*;Z5N8S_d:Fomj9%E72fo@%X%S_2 1*M1q3*ClM2@3,OZE9$'(N[?tZ^7ClN`%]t-k$[f"#ZW/6DC$WF-&M6)^7[0?bi/!L Tgel;P APkH'R_snZ#YeQ=OD<X8?*+hoG1[,h4%T<'s/tF^Do-0++JA-0J'\0##="sbr]@(JLEHZ6n="m!kT!j4ebJrM3U=mVA.k;#$oD6s"E=Jc0ag19`+P@Set#o3<\BkoI@V+`+#^9NFs"i+Hp)r%U8@:%?9Zr;$kO*<l=%?,fE!8k3X#*aaod&4)O/_`l6.ec5`@O^&!%PD+-o%#'4NbD%rQOV$_;T?@\79rerL@q,V/s6M,AA</SNkg@T./[gb]GoD=Uj*/_1[U^B5d+PL$H,LC6O0Bjq7#ki<<Zjd3/I_pj2^h=<_Wq.)W[<m;i5"To[7!MJ7[Y?=2&;@`fCMM+^*T%dLUHqd1g+0;f>sNOMghCH'tQci%$WPfA,Tjkob\\,5=qAQ#&*#,h`.jDlqi&qXS#e%94D_Tfl&^R=:0he\FO!!ZLX!=d&,8oK64Ab*rT=9IQ.lHJ-gPb<D2lI27,OT(jY+<OG"C$!A=?1Ss*,,fp"=^#aT:BfY>\-K'njG7W$`moQnl'UsIlA7Y>h3[$.50@m\UFFAbKPekPsUg2?A0*@-cRT=mP7TDER0\1gj+WAQ`i\Ts3Z*c1?;jqQ"CQ?^L4=;./Wdf[`cEsFdr6=0QD a18&gs"AW7"nh$AH08?M:NkAGRYL=q_6".6[2Q14nKtMpP'C2I^8/OR!JfrU+'#q[*O3M4L986<pEkr $harIWNoA5\9-pb2@$]8<%7mMkkZ< &\rT3';I<R2 a]YsDieV,`GB#@tSkVA9CS\KAU?%p,\cTRk 9FOAahlL^XpBb$51CT]4'4sBbGt[`VBda5FPg`O!AP`H6:?aFhM2t=0J_'>/%E< Ao8'5X8 O[&@L._>$ZYe1PPY9-7C2# =YUqm+;/5p2_Ann]N-lL*l:tX6AjBiDc`e%!g4;SNaV)>99N!?(KPQ0Q:,]qL>;,.`EUo<&a$=PpGhXOm)t _&;8#HfSRMR? />clW,HkdXYVdjr`:9k=<[WZ7EJ^2l$\=`lM%+_bAn<q9]\>d[?9>jn_n8RL6kpI=kCj6Qg_!6$;,27AAe#bV>$3gXJXD`>G&VB$#H9A lhGF-[4.2?-+;VV02.1c%2Ki3;W[I2>qa0J4WM`K$;[X73<j&dWeZ&sY\bc0DL3h6Nn X9t<aC=Z:tH,A:S^$?cR!(+Hs*)W41qLZ[N$KHetJD<cHXYCZ#gY`1<UeW4(4(CBNKT?H//F.)p)<G"<5gt<br,fBk,XE`7:TQ-A%d65.c-kUq4YA!LN,FBic$fa:NPS',lg):<8EQ7T`X<JBrHp4F1'U5Al5F_[8;MMl:Z9;]`4c]e GaAi e9cMc<<Do__t3cPDb0A%Lee)*@"c[,I3;BP-Mbi\SN;5.MF4.cD>`flB,t;e6GRh)NXkqRt*Z>f$fN%_o&6T@0QjL+8R1O)m?!>YI^K3tWc95Y\;5S*9?Qj>]h._Zs^EQTJk;A?YA^Q,c81pA2Kb C<*dEQ@PRtlj\A,l>W>GBA^=D/<9jZLV8pB^Qe8S#BiklO0EQdM]Y8Pq1^M1;rmMHLUP\$ Xbodoa%^'9XkE;MmRtT;!W/e/;`^&')H.sXQBQ*d<Wc>%EKgop`o!(mi.EsCk0+lONOnlM+8?W't^k)L\==d=l[P5GYAqgPS7TX^C2B:p8\6B9sZQh?j7jrTk[q@!$o/G&n@5E>^7&<U8&c; ^3B;n?,+Ea?sfTB_iD8%Ers@>%A=-h_Fpm&`\/)3?GSTBWjA/6W9p3bf5<A(O% g5ctVrEbd?K:=G'EpI"Zb,-o0/A;?q+AqRN\&^Zn)Z,ti#\5t'D_;NSt,Gd.EnRj0%JIbAY%fMmA_I?B04#>Pm)Wj 2M>5K(<gqi0/Mc9kg=5!aMcd\GkTA^1n.DBj;0DiY>'Y.V"rYkNNDVr?!G;qES[Q7)&_te dYVBJL^LUrQl"25['"`GQ[[k2>I02O^@0sOtNq#Y1:T__V('?=WI_0&TOOBe8f\Qn42^n)?8-YH7DEUq;lLLZoUh@ih'Og:-A"WAK6S8,'/[5/B TlH,%,dO@; A61b85dp[a*F-70:9d`pih`]V:_XcH\P)t k67:f)85Yh6C,pXq>#aC61*5r(agq4K=(,2btc 3CVe:>tKp&mp_;<8KCoG-I1-MgYfDArQRN@1`ds50<AFW70S;lZ:Ger$V43 Brg(]>@g_b:M\<?`,^@n6_1>!?(4U7AHQ3'LU\=l?CG$-,VU\ii_oUnOGSY;f%[mFB]G+e&q/P*V]h!abF`R?;DLen/K;&#e/@V>qZ=cK0ja4KAZ&WlmdCDeV)BA[Z?=4SmqV&lC\%g/6kR!!H)'k<(Sl33W')p_5ko_<OmtFT]%eF=C;lUEJp4NW;BI& A=&cXfbcXW(@XtAbGH8< ;Pfnc&o25si^!jHl+`XO(pUGK>,=q&nS7J7F.U[Phh+4f I$C'6FNtAn[@-&p"Lp(!q(r1FJYc$Zg!9FE.e0JnY"blEYo;r:'Asf(P63)8]7@!o &"?dVC\$n8@^N4GVL K6!:'E(GH E8#okq*n7>,kD%arjH:jgt@p_&6+pTO7;*=01q] Zd@D\\DN@/G3-<[Zp]#">q40K#E@LH/I(3ZQb!NA4cO0B'@+D#@@9naEr1EGW>/4bBj.`lablik#;?\Rc+":=$?MoF5Acg(TDi^ s#)R'lTA>89e.bmM;jKbJk5A(RRJN*i(`d&)5]$VcQos1/#2phBoXB_&VID` _+$V.@8AA`k@Ank9)V36/O.3Q1ikgAl$TZQl5X 83(?dTPs?F!Mo;9L?AX`Jbm[s*2bb`G45<-NM$Uc/ 'rV0!gHW7Bdb`2."U?5`[Zp%Y29@F[Qn_s&nnqKI3o@UH9:hVoH?/+eF(jk')AGn%F1dp/PA 1pstn8fRi:^AL^9sF-!")holtVOrB3f2p6^LEcG?!gmdh9tP<tt5ARprEeQmgB481HkU7i sJ?6+n^DtH1dJ!m8g1rkKCAIqEj$Nt8HnD<7k;]\^M(`0;55dqE[ALIqk"C\<XobsWsNBn (?LX-/6D(=sT+K_3fAi1/kn1&TX<d27G<:htfRBI9`.2<fmRVPF#h:Q11&/T n7fIPA6.gTlXONt'[KfT=MnG2(fV8Q`@KVMabk1t-nX`HJ(V+)#%%4Wo&^l\HD3dN8E^``; G0DpaRp0; fO@SqPHeUDdL34o"f_.&(\9YX*`)o3XtAYi5E&T?<]Y&S(`2=+ %f9Q4O%r*f\L%V.s8fc%W!iY1Q\8[PT.`nF#QO<D1,<]Ac&Q[P](:Qs..\E')<>\`YU0qc>_!$""8^)Ebf!dH#D74(H6K"e%+hNJIfqCh/3BYAPQ\Wj`-AI28K:3Y2S[]Y4B#3_N)X8C I.h!P)f84RgSPCq5B3^J@Y^E.WnAC\sFJ;!E!/bEhsFFSb^JsGAA7E;&%P]c+P:1N3`X5?:A,]%L1IPV]H@Lclptin_V&<fbHPR4O6JV>%3YCo_#q`k,*ZRgL PJ[UWm;C8gkl?c-N(qRHO/pSq>ZOjA8&'bm5e?Eh]9j-slrO.(WA0>"?pMKO`$3MdSGlj_kr4#0<#Mjd_bff'0]O?'gC-dAFK2YKrA%MUDn /=g>K%$mIpkWb-oTWY33@42n(*PNQ:rcKA./AOFI)o '-12j,gQj_&fAH42)VeIR#"]>^B::]DQgZDLTG_9s#`\4\s[BH6gM(k: +2n2QFZ1!clKpAjG7hLn.F$XE^L_SVO*bU<XM*\W&;-DXMjXaaU+*Og'-)=m5nH45B,@q'\..8E!E#;r4'Z@Sln-[[Am<.:CHB00Fa(0G1K(@dH:2tUNqGHpK$W(P- TgRXh*49m.=hAFsq/gS"4[bio !A]C:7(+$[bo,gY@8jQ-&=]3ohbJl#Q1e4#4<$Sd5Q$E_<sXD3glOm,WV]+j,%p4$G8m:Ofk%UmNdUk\6se0lqt?e19UAHb:4Chc;S10-UPET]bR'RpIja)8GZS]#95_COp!ec<1jkMS6,&5Q`gJFK@s[[#-*WqVm:Sssi_[7G#Wlb>+t ?[QX:-cgYH]Fk_?:/sKq22<6L!0hnU-m`la2"Se[s3TOG\U1i`>8]*,j+A^l 33gKkB,l)a );aoOlC<#nf?hf)6g[58_'A(N`> t2f2/X]ZAS6JhqllB!h2"Qe483 !ne;)2$:jbp0G0gC\t3/&b2nRoa;`lW@p']OIIBK&Y)'l@$I2kDEMD:*@:M* )tCf ^:JUa+9,r+FG<;;R*klWW=7O?J2"(4>UUJ:=ismVp!o!.Z6_4aM7\op$0YAK\34V-LR*2ISSKr*+Z/j^L4c!'>%mW%QU"PVbHEcE^=A@B:#L3g)N'e9*m]B8T%m#p[hCQO"k`8,B^j4&Z&<nX*RA#^HOR'M=,53`*RR,Z[,.MThq8BFpCA(sBh5*JOC*(9`_2-$QLUdc$WZP%&`!dg]),$s>qHa-EVlGbn,^J&hG9'9AI=Y3P$tE_4AW4Y^T.p@<9d;9*658d$aS'5f3lXJ'3!_U3M`8JBC-G(FeeG[Od%he_"%Zo(,qo(c33 .m;:psTHUiPU;^lGUshP%5%,l?(]Mff;n=[1Wgb^Jf6Q,<i.M"GO#@k'Op@GlX#>jIGqAGSTVHpWL5bLj'.sf.-UBjlJKfqd_d4rKEL,i2\/Xciq_f>44PRpROh<#^&H[$(RYW*^,/Ol I;l^9&fj<Llr`)PF4MGeQX0Q,rP]Sqo!k@5`+N]i'NE&kV@WE.KMn<m>'DtNl[(CdED]'QdET6dAei#G=#f,sqR@AQT-&1Pc)]Q_O&6#i7$iP@>lFZ4],&-MfTCg"*'`Rq\Hh5i ,L#+6$:V6SW[Tsi^5iG-t3Bf^FahQCOd=q*[R45bc=?GfJMY[cR"R"j9,I=EK;bh:l/^S2b=[8+JK;tZp0p+V%:D<B,JVXfo6Wo5LQDls<%5^fJ5Vmqi^\,5X224ZK\%:;3H`8a^1&-Ao>/Ck,gN'E,_%DkBe<m>g)a$nf!!-2=! >d7j=:l\pIc!A'I$p/]c"n<L/NE-1Qo4Z:@ST1b6)dQG=NUfIq-,db`a^GSMm"._AY9GS?i0*mI0gOdfr`lX?Z^ZF[1-&l:5EV.!>P/),.nt@/,7;+KVsRO-acIj`g;m[^#BkIZq_?TA990PGc\.ACkK/orpm:'/jT9[jn=L8C^-f>DhN?YX:AF&q`t/)=g?2[Y%A-2+0:Z`Qo`fH81%/d[s9oqo\P)=Fh`Wr:ANZ$1\@RYHcJ<:'He lQsoo]rJONQJ"3(f\YqO@HF!(=<Um[kImM3-!U>U*]\1Y9a''A;,IIPeHPFJ%2=*1FsmnZ[ANmVXNPRgJ]B3=g)37Grhd_#mF15;O&8<#?(W96;ImlG6EaI pY8AASA02NtR^I!7^f9k#.=R=cV`-,_&QqIFaI%oTn7an-!pO;)N >JTTeO.)6'C"AoK9RnLJ@+hHRj=[Nb!(JY4*rrE'R0)qSWPb?C;Rl(F9l?7:XL[/DNS#+QI^B1Z7b);nIVsoOl9CAh-d-- \\PIN!S*>-JL/&-RGcC1/ aU([@nG*4AN<(.7Di6cLgX4qq\D?M6.@Fmod%de_DD)&'9-_m&?nrGVEFnk.M)UW$i%kPAKUZ%!^+,2@b'Fk?4skJGKNdUgZdokFE" -7']_m. YO>beJ?g[Y#A5ARiT(U.KVe4;<E#\EbO!iG`bakX:qjjD"p5Q0?4-\e!(2QZ>:QBgOM2^OZ(GK# li9G+rD>P*5o,H/O1I&+jtt\Hl:Ogn4p@@`-"Q/jcmS_at&C8lp-c`DMh!4JXYN$XKYP(Z#%gHI EV$qpVP_Q/Q:#5j\=bi]bbPUH6]sV::AK)HT^O)P P"+AR+S1OTDd$[Dl^!]if4?&HP ITD;-/KhdmBaANA#$Ll4<&rOIA#[H583h$0C##K"tCp'n^_>s4=lrM\5SED,/AF^Gn#Q,P38AD+([Ka);gF43.fV#2iYG]9m,Rn$t[;<4kC:7DAf,R*bZQE P;5MqT$M?_HfD9@];\?U5qsqL8-88l6d<C 0H7bW,,^c[#3;-=s(H-"],TQO?%<`L1Z pXPs$%Cs\-$'BX!PC)16#Qq_WDTaBN5F"U[;(SB,6`rH6o`9<]$K.>_8Y+ntTHYEc21Cdaa@Ak=]3$2?CN8Y)qY;H?XY p+*;IUdr]/5^P0r\_335Ek6K7Ftb$?Zbht\C9[<4)^5]HpA$T]DKTes\6aiW9S+^+LnGOqBN,Wg=L7pC:;h@o5WU`lZ^s]aNsHJ2$n-?LF5.a.]4,r45grfiGJM:>[c?PqFrm:C6*gC4[MB244"jJ=>KV*h<pDlGdMJ2Pc6rS-'H9I.0@VAB[eqgq^+VN2&=Y2&UOn>@IAR:sA!poW,4m r.VEq5lgo](gE3$>d\r<_.U[WQ4[OmeY2jZYaF!2TDolY'\K;S_!L><t312rDS>Y9@p:D2kGjCdA\IA_I##qQ:Vmf:dS?O?=][Lh?OQ50S*nTHOoq%co`Eg$&7<=0f^J\24O@[Wl%p8P,E&oQ+S9Z^m7k.`Hpr ]cCLnZk<c<-iSdIeBg7c;OkIf);j*i$nTV:i^DYhQULG5#UF8%TYHl=2ACj-mkW_$J?@#0B#-q>S+V:&NHM(drJmnra+7SHMDS FVt=aB$XD% HqbAg]"BgL*!lGngo-!DW qI)=A[(jM:YV+jsZ!/Pd>d,6&'^$cDn(U)lDLN\V(@Js+kDN0DcRR\%(@:o32!p#PP6dDP!],@[>N7A VY[eOWZ*@^lWXZm)*+P[B]1+%oY1h[hma#L@#_LJT5>e[Y[&)RH7D^()tHOMCQ-p-k>f-XppYP7a2E>9,b4$Y3N1CFWr'He.?;DDHNqAO83oNqlFR@A[?HJM>4r(QJKfM;Ma-++]'D<^G.E+A;Y5]eVl>'t?S9%-)`3LDd-g''5n<t.aR6SJlSt'aR6c?;NA`,bobV-tJt4hm7sA#'p`0[cMiHbNp ]+g'oa4lTED.MH5#6m=0(,[#Ah<>UQa^`#a'HA;d;:Nnl1p+SJ"(c !$27gl@pHI(gSSa0*9&ggk6BJj^o\!oV(h>oSbg%/BHeO-mQc#q/G?cGdN(T/1&>JML>@Fl0=I4)<e$@VPa2U/!1ec9S>'?9pA&\anPs=2+Eo9c7=i\psA?5!5%Zg5,-9n^jsb/cU,N^3LL<e\rMD$+*cZiPHfF<]l_?/pr>(hi #9lYqB,ma6+F]j+jtnHme!nd!'i-- >eBc/8nsP,PmfHT2ROo'dMQJp%6j]RdBfS:^IEY'b,*PqV!Dg"4($Y:^Pc"Ta!(k5SR[YS#Fr6JpGWALb:JGc__UGiAeXIoYAE`7( :YX?cH/Mt"c-WXD '@Wc:$s^Bod0RiiQqI4@ANe@aY]:+0XHq*c(p=sW*%tP'=K##Zo>CmpFq8H S3^L4`<0^mFrnM&[[`p:+38A*s1/CT%GU'qQnsTs7B_2@Ab`NNa:a@9A<XA0_NVQ*n564;f.PTA`DhU_*&,N4^^70s%ptqQ8=Bc9/j+=(pZlf31m2UTL8'M:#d\K7aA22tH&ICct:YpIW'`Cq>atSl(BMNC<,914O<14R(V*W[VCsJfjVJ;4<<_f@`9bIV&LBHY]RN2T nIVn-7_Re;1OkUg+XUoY8NsK26]>c%eaq*C@'>K4JS9Q@^`Ik!aso]nLZ05%(dtNH3t<6Z/ZLP@Vm911nMb't,d,.\\4Iq9[(tUT\/:[jO7PQ1(p>%/ Z2q8][fT0^:dq]J8Dndps8(WdVSpi;o+loBSpA<(KW[_B)[S(B3fK\&0eG8_^mOX:@_MiD%%YTeDg"M0+#e"nZ&o^VLJG'nrU+1K.^c(OZj8c^IH;%5?A';=sO%fYJ#mkknh`O\.`&nO]g"-^1%d7!;EBsje\tgXg@ 1LbF7(B)H<K?`$r=#j"F(0rM6ga`%#Q`P>ndn)UAU-SpX?.IVRBm)hC5^3XSJQMYo+L9f%QkYrg;:JBrkrB@op(;oXJj03j1[:'@VIN*5)*#&O#T\nA/-UGM-)_AVo/m4N,U0lg>cTBs"X*AKp1L7qfZ3(Q/7N2B5kb1!B_.*3^1cq#]Z'^r>JcR(Toc]XZ6l+6@&A_<?LFrPo^S/L1j#/IX@fbQt<HJ#_oO0)nr.-&Qg=.DS^JG<BAbnUhAdJ'K%)moA,B/>PFjDGs!Xs+V& $=kNhG!d<A.3!jLiphmV2926ifBat#+,&aUR&+*$@"#\d"YNsAVq(C#Aj[A55O9L2f=<-rWfMb<<A\)/tl#3#]IodF3sMjWXBA]I#N4:<^=D09gQ`Rp%h 9X2LlEkgI"Ds#tb8U/S`DJYs4V'$9>e10LY(<3B$L6Ng%,O+1KMe7j]qCD##blsi:D6^hT0L2E/XC1##jJ53>:[m*!<@8smWH`ohme=E<nVb/6aU?ZrM1:_Vo[# sGf8)Ye/5=26D%0o-:V]qfLJK'i:<I#O+jZ6)KEoa+h_`9S^(pX<$A$!p``q-O`UfEt.P#/EN>j QOc4*4[<YH))(9e^8FUbh\\?e/AShNT-r.Z3(g5KZ88CkJE&.?"X84e9\(7J`*9]@(]B/F#Jd_55o0m 0'> S'?Jq000Hj)nS&C-h<Il]`q7F>jpM%OdL"L93iNbhBl]69Oem:CEF4@QoJJaca\+sg'#F:=fgU\e7Uo$11jKI!)&1H,'8EWA+-*eRP2j,-oBCf98A@$6+pnajZo7oaPX:`NCbtfL-<ZDiG`$i@78m\E#8sRD0rLr2aN?)>/G6bo=(o&[V6e<7B=! 5@JO_J`Q.>DT'hVtM8V-OeUSi?MF&]--F*c,kS@&;4e:S_\VRka?EWj+;*aOEtCpgL$r`@fA:i#O\@p`htpaOk@h-4,DU<OjKSIq.Z>LE>%!-0k`DDB,,'^(GhA'^8"$8-kZN5/32%YDANP=eUi\$pB62fL",W%.lSaQTa3.?1"Ye54\9RtZB+l_e%>RT5bE;RcbmS+e%<r))S2t>0 &&eg/UnRGIHB"]6 ZiA(hHW18NSP40lcp.BkhpC\44KA3 G][Jk(YFR]t-c9\17nV;XI?4l_>IsZR3Ko9-WNm7*fV=5i#8FE9f; sq7tdJ9(W-WBbl+s0-F#h>H8K/Z_[B\Y>%5i&VUIT&T<62^%cH6D&r%U]9>0M^OC1\P gd.4?^H/mp[A<i/+72`!Q][M!).hMV9Lg0&Ue RWH:>^TmW<0L4W>1EfDOG:M6r#/+TTi*of>6k5BTlGm[)UIJ"=8]s@s=G9;^!=7?4'KI$"9'R%l`lpGhUBJ]8ncn>D[?'`"fCLit50"Yd^Xt^Q!Xs!>8=j]fn#=Ff9F^b`Q7p*$!)Yk\=hps2(4"sVC"o]k51ro)`1_6[,@<1DnsYa ncRro!mM!?$n5/,?'rnO@gUMmaW:Bj%M<G &6]8^1Vk7\EIS 7.hEOaf!`@JkdTni7VZb/HEI_lP%#`,sJ7bKioQmU-\2An&C)8o1A@#LI?6eXh@c7nXKCbp'l7-6UW0S=UbY[^?K!(A-ss5RcH]8$rnlA?255qQEYR^gSD/`3jh]8:&jre/<#%d1nX7-$mH6AM!2S=dUQ7')cDIshAQmChF#5^<[t$+QXMqGf*5ZS\kMsR"A4+&^\si$6l709m217`F9&_r--k[6\?>bI/2NVWgJ)-W^_#93Fc35fm"M*&H;"HY;A85+eKZQ&o#'%^QUID!nsAm2+IRWJ78+-Unb/<=bpZrO";8mC5$j5q=qcmg<JD/D M"l:IWY#9B-EE4\q0QS]e).[]ap9M7U'a0bPA)$Jdk9eDKA_]C#))`+oI)jl^16eA2-qqGD0Viq5L/40;?5V'kM8sUqbimrjr7$8 *W2A^]\,]4Z+jFG2iSQ*3'ibc8n"Bm@`#<"4MS2N9HZ6:/pd/D*_F2OD"Sp]Q1*84BbMNg/REY+7O^WJLA3r\jF?5?m9?hI](^ 7pfcSO5)nO`,o<C5SG=Qtj r7.^j?8$6a5LF`7-;,lED^KOI,Uq`,7)o9'+eLiZltend`rq&]4YM.QK2hCt/NKUXH<HAU,3LE$9.<Q6I#VV'AcJ4V+l<FQ+`jbSO.<KtM31^V #+LE;hYMe5;ZiL N5]l\.nTDUoP, p/0+KAf-Frf.`9/m4.;fWC0e8*Ak*8Kid=rcLQ/]0#,n&NOi41=(PVU0e,XUWLO2=[gX;[l;s\5DM-/(W'M]1J\79.JtP, 7mEQ@G.=q?40Fe "\.^4q9j67(k%*9He?Jr$Dr4(@LB3)!'(g A<]#/J0TU4io]AkCQC#MI>)WJH`$D?>l+0k<.+-YmXZ(,T6"6h1QA,8>D1p'!(N=!:3&gO:C$9o\>95oW'Q*FC-iK>`IW0:[. 4?FYIM[@%EO;legl" 1F?,GoqD[B5*3NhfAj[a5oOk#dWAq4!qhpi=67X&-N+J9 ia@d.VYOe.M`K@,"""fE2sa]I=-1o$  U88DcaJX,X(FTXOb87#\W1@='4"3#.BsP Qm@s>$I5+cn@>DAn_RB.Q!>[q:p-c_Ebt-Y4leG0)8nOQJ7"5Fb7N(*+)9WtJ1a[=j4A@CJ!T_r/[-!gL[JrT,t@k^iPAX=roY%)G=W:mjl4-rZ7bK+(B[R>6LmlF]]nb6m;".rfrZAHWoZ_bO)b6#?lNc^ 9.[UV+M1Kgap<)9>],RN9(3MF[Z.Ro5a ^bfm,09"iFK 9S37-<=A-2n1Dmrq4rA<B2T-%/GZEMM?Xnr7oC>YbF;LJ++UXR_E[jk`tdmUEaEB\TR`^ZZ5+A0i_?gHjfS^c!t&pHFc73YsNVI<QXs=]J"RF"AZS1%X2k!=7DN`DYr@A*%L@$T>[)_Ut-6'e9U%2N&&r>\HX`'GPo716A8R3C#rN[<2,V_lZ[?QkL4>R>f%EB5_*Y\2Yn2q6K@"7pIlen0cG=dC$hen\dj.ho-0'Ik. c:8(+lT$Agg/`LIt/<2PH3>$oW!Y+DAo1T-"YJf"_`nWT_)-F0-0#TV"\*,/Ai5VT@iTnbAI0ornM+k;QZ7hkX*m=LeIHtLUPD!i=f4E0$h3^C/s+".a0/jgoGb0d/?:ID0jt)T%EL4PLgpqkWU&;d2"]Op#Or@7c#p1r3K&KKUs!3^q:W<rjDEAdjfKj9DBfaGkK]UftriLm@eTU9^YZgAq'&lNr=e>-B3eAfc[A_=nR3lN\hG5![te4+Ealfg517GpXQ*cZs]US@No>\OtkFUXqs`e-7#3TYYX;;p= G`kGU6JJQjAChM9^P+S>qb%ZVL*a5LrMqGjB.h lTo@_H8AlHXl1s_LHZTj6TDPX#KjrO1Ph,rBN* 3 m]dQ(#QU#5s3shF,*rZAW$6Sr9T;4WAQhtZ%3+ r.$%pDG8  <VB>M7AEZ*m'k-3N@(KnjQJ3"A*EF/h/qst?U:Jfjd!)MmP1!#PGL9:J'$sE M.Hf]]Frld-%*HUVWsUrD%?K"F/gXPe!LjmKNSM1tJC$NK*o5Le#ors`6iLUg1=2MaD02aaZH[geljDkU'qc(tg&nL'102,0V>W?pZ<aJ2X7@_D*K4\jmDU! h:iJkSl0bA7`R_l\_W]Z08([5@a"ZA-j3mk[]PMZ`$f3(;^Fr./Ib%d@thJMa3=tcLm"V'R:hkKk 7L`oiNn$U('&*q5ng\&(bA+(XWK=[^kEdd+b`-+/W$:t0-AA\Y#m]ZMdg&-n0l2"W#_hMjBC6fhYP@ATY0H>-CB!:$H\(:dsB@b=$R+"Z_*ZFTDkp"TAD9bs.88&8?BG0oA`/6_9:Xfeo3J+[BYcc&Dk!DAhQn/HO&mEGsZ1A1\%+HmZ8AO6`J T!3:Ggj/R4V"?gW2sXh.2G``LIHD`N5lC8-4X4-9nBoZfAH!;Fg(<LATBWW<iHG N;14)WF<AdA*dQ]%#JSJ-^U9I#h=@k\*X)Ij/>mq!EO<j07jU^?0JMt38[PB:3HH)i+,+V#1,UNOs91c-i4A8*8+ec0KBSee(Ye#;o%&ebPaoR4X*eP#lFiL&e=A',3V>!#i%Gc(1ZE05MaV>"b"OT%F[U?Y<ghXN^:[65iD\*&2VNb!d1(aHr9`c@V5DrKa8\rK^W=t*jhp4 )?g^ McaP"d<m3f0[$1Q<=)LDDH8;& ^X^^?RK#=e)rqV^F^lB2@EDpGi77t=tO)GaAXT$=]`@!!L$VL,A*cA\R'XI_18K3WoC6gfpRcM+RAtYQF T4)!FX^JmrM[AbSE#`gZgMM=Wi^\UR06PK&fegH7NfWAr^3>B.to1!4S!WG#g>I-YU"s9\s*H!RTr]jS0Z)4[9ig)'"brRKb[pb7 7M[k8.B]i.*)oHiFnK/Cb.qr*OkY@jc5>^K8g;gaf;Eb %"#?EZM"6[H,7a+s(XFiP)>dd%(lLHTUK#4pZ]&sJOa,&MRZ!$2oGO&=7Rj7R8\pA/p)0a?d6htHH19G)ej6sGfjWsS2@*1^c"$'0LEI5*!X8CdC%j-99XcPs8X+s7H#H06$*4h\^KfW.U$r#Tb+E<b`OTUS0 ^P;h)/?IGb*fCZn.]LA7A^`C#(h`QHQTVCZM-/)VG:j/^Q]40b!jN!o b;e1=06?jb6eL(kR+en:g..fC.1%9?Qs4>G@Vf6sphpDc:A5]9hkD7`ijZd5^00%_N0B$5,RMN7M>Aa;*Y5.F;rFnK;E'):<U&Ks+Z]5>kMST!r\G=<W.@95ZEM#((]-A;9@-fH9R 'W:7Sf?f/1qO! X:G.*C"kA@<ZF[iV_ZnhI!5-dkP3[E-P`lSQ>^DjsGF>!^\4L8>VY4$VJ\WUpegjJb5ArjLWkJ8@W'a#p(VW%7S*YSI;IH@A\O9)Y(`5jb]F )5S?,I,F$./qc@SFmHfnFf!$bW+erR:4Y99,OB;caB.E:G/B>AnN)jF^75Y)Mh'<<\1PSGUta0&WVn>&c]ShG#qb+)fNmE(tX/13]n!'<J-#*1c^feCND=^TI:"ssoO's8GF.C._rA9(202EWB0*r384ahQi,Y6-hA&g1S_1Gt'X0]'OFbi[cF>l:EM7@M9VX_AT$\[IsHA#NQ+0:gZq'@W"\XP,<*tJKl#E$*0O[M1$ii3;CA.>bT8(1pp4+Z&mlV5lspqsJ)?P0eXGmV%CqZ:P9`KJc9TQJDqa_AqVgGKJQW`\<%>&@"2W+Gg:akVgpl1><:,N[K(d3H[;d$L8)!9tn7 >P,YPND1Ij%bJ""!hm!>VK"AoY8[)gG\@ F1^G[m6=5Y]r$knf'G)e20=.Kd;\c*^*;"Ds*O$K/kVOp%PE33M8C8-3]Fs=HH L](7Xi;BBRDW<`p<&^(IXmlpmT#oQtY>:T[?W`Ze^_' %2.93Mt. $`@c`k=h/nPPf\Gl655MMb//13lm<foXJ 8 +AqqQW_!LBF_,,KLLg@bNOSkK(?YSKPWc:+`1L0l4D49UQKlkCB6MeYp@Y@Bdh P9P"WVA@pn/cd\N&LU^96PA?&FZDsM8$R'YAJi_b$c,_# i2g1+BTg: .%6HA]ZZ,U2J8W'Qn!Y7TF+t $m /5R#RCiRY=,07#S:Z\0Xl$4T\\@>fahEaDQ(+47_f6g)I?ok6C3DmAbbj@Erg&S7[eK\[C2-oTtY<`7AU+?tAllfsA9AL^+5!EU?bD ftpGZD(COq/dchiOg;]F7b2-Y1_mcq"-d^ 4d75YdVN9U%AZV:99,YIPrG'a2-Atnt<q.<&-gC0+1*%F70/$kqf8lH1i"9/dIOtnl8cUEAqkc_\lG6BQFc]p+m8](X)i0:9I=8\lJD\r;5et'3ed&6%$g<[M.kCG[ifSimQ%Qf @OD(jJT/aojR\2_jY\U?TI:IL<$V``i+[O%M7kh58B0p_5QUrB[ ]3C11$<phVV^6Ga>!<_^nER.*g\cp, QW=?8AnA(A+eLrOJ9Ea4UeLi6NAWJJD[Ai$+E?>R*o(WHjq1?"+n?`",]k3kX;'^SeI)]2."\9>EqQo2K?^iG)TmRKp?=Q\DZ"__Pf^MW<KFd6MTqG<VL2*p]I8O=,(T\^hf+-WI6El;9Gr"'ZA"p+?\+k]M8lV.Ddm50qO**ffH4*Q,bkBsTdUT=g[4*pF!\ir.jAN\<9>#&+Zpj=/B<Gj8PaFnMW?AfSmXqKWpU1&O`/A@=O`QX+30>11Wa'Pk[-.:pr_1.L9YfmM2NT/X(6-NEnK'Fl>t\__fN- ;baPoO<4E8tNq8UpS.(W8t[_B]oSl/A:& %(Fbi7t55lf3LigGUo$s.I-_=4,^I;^)$d&92Y$_5McBg<Kdq;UQIs` 8^ssWMa@[580862!#5C?S^T6;1cOOnm#(K<P,jn<H(j_/9$@pZF,hZt]7)RL(V=9;`9paOi7%VW63t0j9T].9=\.4\]ePD1HKGBoq 9/#Kk"QWWcoWk4cC@=on8CK`1sjEE[YIW EE6r9)$>`]bD0npl#ILcRXjMdP<&@H8HQ:%W'!p-b@PjasM$c!tKpg`J-d</W!tLM09@5KD1"*:T"+Ahka;eG>J-1sjS5+cAVplC@Cf^<AqsfQ^rEFgjqd_<o/47_mP"mPLk!>F(k%PSj4/Y6h+!:2pXa#55p?s0)oMCTgq+mZdX*%,g:L)MPG`qi(PmY8V=9:DOa]`H\MeX2BUd%GYRWha;j8kkdDkb!o6%.c!^o=L,U/Pnd[Bm35ED] @N&;,!'_laMA8k44iGQlM?S'F1\a[qAlX:$4@Q/^jMojWh1jTBTF@$SDRlP,%"W7X.-RSkeK*KV;:tDILZ5tQUB!%\P.HA5D>m!q,qVD@r1+lOFE<>n*7D0.F`HHhn0q d_0nFK,1*b^^40GoR@1lSKZV&N3FQ(BDcl^B>3!PHCY *E1bHs*Sr[j=BXR-k/6V0#6_R>VYs:VoaBVCNA5,&r#;c#F@A1$tH/V@4HTFTHA>%IJHFV_=g2_Ue;-b?)pM&0BA`(`h,f.XL8U2<F(IX?UbDDV["!#R'\4QmFA9EP\fkE:qE%^(P+ZnT'P4]22'Q$ @$H+C'4S08@G9A)?HTgXJpX&Yf*GnhAJB"7"f3/2j(NrA:C+i)g:]Ss$ TsfFbZ>CB9Pt#]HNdPKsQ"CXQ6MhQ )poA[s&c F"RZq;i!=DE[Xl2MH"DYV`D8<*UcPWP&i dbA[((MNLT>hFpROb'7W9*&m,`%@"40b>aJMl! 1gD&sDRtAd3I2llc41."H37l5N;$hj,qI.M0KO/:Q3.f\hobc1^e?4CTh/HL]9[A)-c d8OZG J>eR#Y/EIhlP`22ce&C-S>c'f=_m<I"\/ABk$a3Z\LI5Y*S:@0L%>S5m39X&(JL0B?>B`4;1`nR$DhTHFQ=*UdSa3:BA63T/D5-Uho >6iZAH.[.q$jVZslOnD)T,=(''GYSAA]t"M+)H>"k8; U4BWgsni\beh.YDfrY(,LqTUA:K.OlE^Q8f8%Fg_+eZFZfn`XqhQ]?%@,X>,nd.V<$]KLbA1k^[M'?,ZNBrEiS7s4to=(bAJ6;O7C/arKE$qk5>2KkO)ic&hPmV,@!Q"2Xi.rZ-i-tT:t^t,V9%rP8I^/nRIR-H^bKP Un)CRl&BYVMc>Qf?tN]8'`,-j"!["F%"/P5:QcTgZVlMXJ']t2A,Y?(lkdTZHnio,ta4J`QQ-Ro;)0[.=D*qSFa!KUsM n.A[VN3FqG:J7%THcciT20Z$-.Og+It']r7]meY3A$`*)UN;Ep9h3hEULe"i<f:6Q3GCQYP#)U(F> a:'^bR"q-J-1\V>CmA2liB.fQ\.>`oNB!l5Af<[7_;5Veg]JS3MUq.t2j19N[kMZIkodDDhXNNl@Lk['\(\#Is_V%M,li?I]V*EI@\sJQWRe6/QH:k<NH3Zgg^W`Y*@-I^_!DUae3?_^V6S=]\'8*Ehc'0E6qLPgL&4X*!DP\n&Uo94>>9[pf^+[C71lGU<@Vh>5Br&3Ss9&,9M?QXKL0Am&*VJAAs>pIUjNE"-/T'@gFoAt"*d;]qj gU-/lRArHsq]5q =UkR6(Rm'(++,o;3[Oo;WM6U;'$2X)/qY?JG+&1Y7;EGl"E%!rk,:]A@j8*]A!<Utcd(TZ7CkEa6_]lJ@9>3'-rBrKlpBjX[&KS[\@0oKa%/@F aGFpV+Ak1$@"YBk/,e-Fh"S@JP]IX[@ZRCkVb9[_ks`jDFpC26A\>A"lg.q_q/?BVN(PrBgJ.(RG<if(tY#M47G<m&TE>YArD'Sa.1 <kh?VXr')f3&=BXS?SRJH@tbLbb+!V_NE'DT=AAq S9hAOSj?LO$PY#*;+Jt5hW;t%XT@Cga[KtT(*4Y]B 4d=*AA)J5.$V`t+(kccX'KAisn.jsO$d4TY.H*^abrt`&UepA`nK/+CEjDt,FM>UAC]P=_1_Qs6%bm$UgJ)..gWeGilHJSqjhYAd+'8jYZ)[YelNG2%T5F#."W:S; m_Jm`#) E';U(]\\hosFM&ib[@OdZj,mdF-MHs"mI"0]JST6n=e>s^]>*A"P/a)#n+t9,V-aI3Djm(FQ70R4E:g@CJ##3IgOW!qe:hNGW.m`0._f":9&ZmoaYX`e@*eC9isRL^iesY#</Nc55Znl0_/+tVD:9"bo#qrmLf?m!C7KP:3q8P+39sjn !ENR_%]%P4$T)?,6D,PSnpJtC+AE]IVb)+=4Z9KokDLA;]X]``a!Y7gD@O#<YWR?MCQRH?)5++^6fOH(ZcB<FAmNo.][>gjoFR0K?$!\Xl8_11k&;+!%V/QN/;G"g"7]4*BX(.F'#[ET0[b8sO>:A:daV2\OL8nIQ6PVqcVmTFb)qs%$D]-:Am>re,n6>MI,4<W8sYBGhI#KfkloZjZpBXiJ3)^SP_[[`ca8S<MTrf+a9#@;UZG\h6j=o@%1X/8P<([@,B./Vic^#Zjq4\_C#+%_P=]I;R-/S*h16<GPe5,A=<3h"3""+KLG8H*>DZ%;CPf%51m?BcB%"]=snZ9BU9[ X/d8-Vc=tqI&P*pCTrS8=VW2qQ[_o'*'AENb$ac$nTZ^6oMUl>_EH)S(8>Bn6K);0Wr(<Q4-(nR.E@qAn'3m$*4_XB:I15Z4V@%UY5 (MkD4i+HkF&trZ/5)$Y&p8[Z'A5$h">cfhGpI=8& on-C)Re4A%Z9&L*XsAAWH=5:tXD-)<C)ZQb$BZh%Wl< LDp6=U068HIT'3Ced,:M4@Qr>ApKHW;AM5X;dd`R)3<85dG>KD fF+`oDgsgL$knXJn!(`Vs o#5mg=J*@DK<M"'CrspECPY.%t.J0>NeAgTgPEQp[(]me.4H=`:\HnM*j!eg*ZIb+EfU_op"/FWl.i&TI]gU<&aBmh5:/HG7ct`aFABOhS);p$q(M(%<C\X>85[[$X(Ab>=%rAZ^?!>D#kmq[OA;W*^Z*R<XPn^ Ji=k`ZHj6)g`Vpi ^H>#O^Q@]HnV(7T.\@XpomAO!o2fP#nsdcZnIl=%eA*YoA>W?^J+Xt>ZMeAcHLs<gABCAjf9SqT4*[g6j(.^DqC=fecRK32iUcQj^)YSp<MM4H"C1KeAn2r5W`(F_ q=qP#qGKMh2l[K*P k")41NAfM0_7&Pd.c$5['?(kY/_>`D_1JkBtWt>F;06h5#4O[4+p.tC5K)L1D/(0:^d(lmalVL[Elc)cR06B^%J>^s3DhVi^Z<Z6iWL7B`2SPe+q+5]9e2bU&h&2nTag[LV]S9FX:jR8^n%6f5$MTB[bn\sS$3h(5ph,Jce@0lP'hcFhQrChf>o*?C+>T/"J4-6'J%#A(o/?N4*lc5mOfS3N,$F4AfNMj8f)l8p iYFiO@2e"7/nE,GCblomBE7AJ9!p3:AMPme &Y`o_Ork6`XNEMo_otZa2N3h4.+c$!+4dT5C1os+jGG@pom5=sbo+'2TtjigZKr5m/pMP3@/+#%HSt=)SfU\329H^*NA+,J\OAZId;&EP_j'j<#/@a,%r=L'1BPiH+.LgHOA%'%?W+lO"RgJ)e<K=#8?Ybd r>`o.[WPo@$2)GEF1BG5%lZC2N7JCB,L5h!3bIX@AMj5%W2LI%;Zf;fH1`PTIQD'-r@48"V;p$iP3KJ.U!*E!n76L64O(oW7?CV7<8:ZhPPZ\E)AL W@5e%8Oe2a9@BqA;>k%Xq&ocVJb,+UBig5<$7d6P&[ \-oMN(V$L9-Zh:Ad5:BX,MA;DXKIfk/^N*$=Jk.aH`0@J[!j$2=:"n`MBMQ9i7^=3*,1C>(CCb:d>D$E:<SS_sDR#Li'__=0@P:8Adk!@fp #VCV-.7f-oomcijYrlRXn=GJBJYJ22?V%('PY2M*r-WoYMO.^J"ptAmhE:S*D=H&$2HjHj((N9@m"hI0G3:GK!YP?n:\9@* m4eUI9YWUUKmY9h[40oEmd+dR&RNtFKHdC`-$C\.JpW-F1C3b-XX9DpNSTZ+o(Tli.a<?IaY#)InH4d5%DI8/9V8n^ M7l-YLA+3H?er.9P*MsCAl[>=+H^A<j=\5qh!m+C9fA5A!RV]M49;+EL$d(o9^t;K1,7XUWcF R$<gLg"J`c6k=7tBD>p.th9KA]j*FQ%\FkMeNiq9+?D"mZS<[Qi(O'Ra"22/:)']K/@NJ)pTdka:"<Be8apUmBr70W&R=NbQ'G2+%hsSLV9Wo:WfdWR*APjM0`n-nDAtDpWWgB.e>5kfC$/ljl"[[G6A,o(r_eKjHPWiJt0iJ@3FS!^'rcg2:]^t/(6BJ[trtWG+DP,b6;l?K:[]/RDo?>!a%e'*NOcmqj #^3N#A?N^M49AQ%-cZoMAm)a"F2EM3;Aa`_\:D+(c137HS3F-2T7VYJ)U6'Gf_i-NG89'R'hg+GX`j<r:K$VK6I,SdL/giQc$E\Hf[^C%C <e; Y03*L]L-`q;@s/*797rb)s\0j,#WWr.He<8IT,ES-3-Qnbk>k!7"lZo8@^"*Y[\X\lI(pd>-B[5PP<jN1>FK3rC2Zt\[q->#*e"$f,dN$[k5k&V6:C6KI8fNAD_SIW>@!k*o Bf@&m;H<jhQ+U;+gACds(8qTm2#CQ7J?.CWAVq?7Jce5H@(CQ$IX"7$mATFZC@i>r8C]IjVF_#Zc>q'5P*H6iARNP1B&)$oqWLG#en5kT,em!Q"c1J / hZP _b*6-pp-0CNBP#?^K?\&\a:`T1Y.k:hh:eangGB8K"HY?n 5Hg6^8:oo>=8tKoIPkWsZUg<L5jc/AZ,:A$]K%oM@"MBBY=\P6:;V`!to2CFRDeh6No1/R@n$7rI+2!]F!;VpFaY#)f%#4\<-r6CKbfohI+sMZ Gp/"8(4_WJ>SjN,NIY\nhf\S$rl<#WmAf%j8rFg,K4F3`]8$H=8N';0n+D$oGnVNKU.F-Y7r0Hd*&`K7A7E5X2;OMSf9,LO0Wl]h8U/FW_d ?Upf>?XjPaO.iN9:DQKA<r_2fo'eNeeW12L%-Gl_*$0]20q+;&[391ji h dAXOM7)D)=ZiF7;1+JS>&M>t60_t)/;(,>^LK&eIknR/^DW#U/.m13+4a"V?>#ABV.>*^;#k9&^ZC2.sS<K 'Tc ]()h%]%D_AZP?Jri83@.[C=!VJHM[>o:2aH%=iaA;*TdSZ+?NK:O:LS.[&+_?>`W&7Y**P56Xsd-gE3rO_b=qHI"%^]X76o3 Q )2^(Y^@ZsHYJsq@A]&J4l+E]HO=T7p(`Vs#/bAsTCLE2^mdoZR(,.A8pshE(kWn=EtMh?_h2d/=-bUH^F<'q4.f%H;Ia-BY<A?a<A'[^oD]TUFDen7kF'+AS;\4$@QLbK`!!!Al@I*/B`HrFcS;#s6*-Z98Nm91HVMq.N#Wo)8c+[_gTX3RXlX*?iqqKJ\^r8cX\D>A_q0jfH3i=C+jmYk0+CYEhH&&^<k(kMX?7m2#sF2TAD<`(Q07s7S-_%ijjcKYa.H1fY.IH0[!"%k9N98B3"Vl!UI3OpGA>D+0 (X9_NUfNDd.*PIHHhL;pma#bRED'W#D2f!P1^k9,#<32j+ Yk&UMl,tgAG]Q79kf^s1IpK'1b9?P`:agbT!eLS@+IiIHI6asRAAf,`4WaiXtZ+A<BdQIq/%UH2CCiQN%BaDrAc5pa(OZmb5!fBsO>i8 Rdj/D8UgIo6=g7fc`*YoXU*L[>H*lBtQTA)=Z.OA'f-F8:jTsoDYLr?B<OC0djT0Fq4$qR$rFha3?4HTMIL+0EcXa3iL2;3YWgee]qGV^4J*:h",BA\>]/-ns9,F>^<"F(lH4KmOV8I_M_#ioPU#Wi;;2r*h)a#tr[">j-Abb!>13#]!WK53-A368__:9$hC9h7P?tnB.'O4D*9>7/(nU#\pAGQ9'/ N"H<_f.XbTYln786*;mFsQ.0hP9X'27a8047@Qd%E>a^s>L$:M!Ej07sZ[/IOOAiU,;[9FdG%Xpcnh,\:qc3:WS^JBH[S>AR;bM$OTP)2'QU<hK7J3$Di _mK&H`9M)j>o1.7i5Ucl?C#p6^btCI0) qAl#l&]p(00.8W\at&1CUAa)Dj ^^!IY?d#.K20Q\rAhXnj1b;Bm\")io*SSVTd_P*$+>' jQP*#]re`4@FL)M2!i;HYZ_k pN US1gq*%UBX1fpgiM'+7KGXF4o`-RYY9O.; "g<hBOYXQ#E\lSA4_F4[_)OAkM'i@Y4.?n7\Aa?(&FUtSQWc_JiG-'gn4;g7La5`tHQp0h??<$*mN==;oiD'Td4,^48'iF>>`g,Vg?NZ3<V2J'Hq**>kgA90(#Q1aqkD9.MG&4DFnhr/3Fb:T0`GfgoXL T'S$/X4_8nb1I>SY@9E)6?7M)iS>QfQC*;r&lRCG,Kleps"JCo&T003jGAU.(#"]WnmAG^rHh\h>6qcUC#l<P.ga#j-?+e-S:TPQ(3pWD?[4WRWf:g.SUL2ma`h,LOf!<WMR+'P:n@N2a5,ZoV"nG"dGe`Mq8f#6`9nAkq.`d,;18$@6];R5enP&-GL1HbfT>dB4DHa(T$^$*rO5[hlhLS@q@ZAOlaid]-O['(8o3=.8>?gA>jM=tPW'pX!aX#IgNA<X:QG_,/S` Y0ip/k0g-Y;lc&#RKVJi#Chm%2X.-3qJo5=Zn&GSC<4MEo3<Rq]"Yn4_gl&/\l@b,MsmkcVqN+/JU9XB&ESQmGndB^E'+BX1)LXqIn'KCl)poR0I/?9_)[dML\O&QiNg6OWrZHinWK,-V4R(:e=F&\6 \-E@@&R\?n:;on`&T1$]5@@%kNhEd`@gJ>X,@)]!e;Pk^"\-:mbU*gdLFt-CmZ@3W_567]2V.I3ntMIYBe<MWtZUs&Epl_jaFM"AKZR$ij1n8t8c>n5YbQVaAX9] rc.Q#K&gC`Q%b`NaH1FAIe]A0%qlG3WhTE13oHrOs0(A,[X/q6G8VAT.%gk>+>;;Y#B1,1?s]sWa`'/gmT_+Dd+lVGCLskmrf;T]FXDjit@=b.`mC(LIiY mK&YFUAi$Ka(,,JTH!)9p^-NkGm1HlQG/"%r@@@c)>]7TDL*G$_1l]&=_('hJ2VpX&NE7$(etCjPf"nHDiN/%>KM\@e/;8C#LJHBX,XKl0$tKE4.:KL<BOq4Y4#A?#<dFXjopW_C7sj:bWOT.gr[AO:p1p7UbRZTeBF)p.M-J%WF60^LO5h'K5A?JcNm_Q?'<$)MSC"EcFE6F;"f>;DHF52IVY-aAmsZFX_&7=_Lr;VDip[U<K/_&q' W%O:,nqc6iN:ARs.*c2$[SAi2 E^_#D/8K\=f-&' N"J]GrRQlR!;\3",\plfO>A2D36E[P=^GPJC(:N_[?qZjrI_)ttY9rF(F9 #h"(<@k%A8%"@ktM.$)>cSd.1KlK7WkQZr[TQ]MK+rZ35A5il]IMnqMJb-U92HRGsAXbF_&[hAV4]<G)teYA(g)eIo0cNJ@RR!#KmAG+=5hK#.cS4[Z@MGqnB j*=YBV1?Q."K7fI[_D\]^'rBM0NTDt$2dk!X: E$=1Urh:0?$7a9r;`pnq7)M^i^+a:UMp.A_2:_V2JV)Hag`R=<rr[`/EEk[B@KP>02&;Vr;l=Z(I4cG*0f/91;r/1d*QRY//(WV J_tY,EY+_9eaYE>@tGN=[ ;K0#E3OeCP1UfSMH14#P;(A&JCod>`_qB9H!kDG,\GPVr.>*OS?  Bg>,m@0r f7&G<qRfoS>XIsjJ?]cK2?/^#)snGVDjB*hmgik?/SpPL<]$*,HkGbmPJa7Z,H<;l_"-//L$Df25%(g +G`X>HiIa<rqa `R$$\ADIUrCd'K>m< [A%dkdB1856D3P#dGQg1?_a[Q8bnRAmskmAkH=p;?WMKgsGB9HB"YDEZN/=Eb[]C&!+Vp@^lGRH1p$G_FG;O:AA*hGoe=4>6:C)ABX5!;/o2M+X? 1t&>8^FmUO\s.UmMO(>a@mR08HJA4)@dEP2mn`/'&+]k!e8L2Q32*'r,Ad;D?ACnc&*o9p@rEV^D7JG$SZLS1i2q51:sgrDtWXI?4Km1c,NHe&P2rUlhea.f"*o+ksBL<_F\pf+sD`n8](PWH$h/G4df`THCo7-6,&4d,C";%*UFQoWOMWrG#T_a+[dQH&[1,\#!Freo'D1">W)d[=bh6YD/@YURLi]GDU0EX1f!Nj(f'^Kea5K1+UO#f1"O!q,hA`]ior/]BZ(iQd#H_2jj.*kcAtq[Bk@hhCpB.Hb+Ud%@A]NBY,^Uh4^m)?2ORP,C$q#pNBkU6NBB#_YV"_,GeZU-'VSU.RRPn5r3'rm3^mXr*&%$"diWq&[RM$G7(+PjT/plUcS\Q*UA-YWn\4;e),MoMYMXV3Q/r$MoHnhrnpqn/)#InrT8:G\JRA>GRfk@t(FTpr!OcjJ<W6GH6DV\Q@M-3ikN51o?RWO'I)$'Kk3A72P.-iZEJsUW3`S=YYth)=,LLDMiWK!EO4R4kT-&*=^AA#ZPi-74k2H=Bo13;m2.%AGP*cH3?9n=2m-"9D$`f5%>_=K8(,`_Fo<gQL%>U[-A<4@Ip3c'M36V+2EmLU/2sb?Ad9];d>t&_NEGhdbs_<#['6:N;tnY%Uk#-8;t;VmFEms(!&07?`?2"0VR"7Xg%/?A;k>A\,(1,Aj,srR9)%qJd<l,g3s<f.K05L`\<$A]4AHnZNJ<\OM.m[LJRU+);H]_']QV(i$oTOfHDaj<BkZH@mGif$*e@knQlPnq%dhS\S!iLoe$&'_(@lK1gR@C<Qjq8>ji<+M*5M+pU9H"eW?3jrE`apa!;qV0UKIT6R?\TY,a3oWBl9k<pXr;.*r&[MmmQAA%$oLI` GEkfsTPN-%5r,"]B=Y[fd39P`"HnPA7lAGsHW@NP&oN!>34;P49"mtO/RK EP6mMmi9HYi%TG$AslA@=M]cN8A'M>#=-[bGdLh9cOXh1.N)?H_kHo4nH\6II>Lq5'VWI&56#\'%qn,L[EGALMb<q#4nB+Nra<c7]O;((3`G=PrQ*=T>lWhAE\]fTQpVrbO'((nJG.^]=bS]'A3_YL^(HM%V-GZS@"B[UtH1\%)-eN9=<NT=e"V$[N-JMAW4*AfN=N&Tjr#5U6;AE0lAA Y:/hmF"&1\/GoZOC@7T'NWX]r_47d6\g_kjXgt#E)E69NBN9%(5X;7n!L*H:.Fc<lU5#,H,gglb>R:Bn6S+se&9M9:gP81lj*h(8RWj`E\Lq"L2$W/rUCCI:Ylb'2XWA?c&=C8_5/P86_fhg05B<=NLpDcR ;rg' SE8'L%mUI-9Xa**8@6'WJ,TTYjO66V`8A#olMgs$2_b".Q23Ai"nNI"4ECibgbEnr$8OD 4]3b=#;A@G-.VYKM"PKmq0P7,-0eSZgl>=Op60pU6=;A%U'LW4 MI;KR#qa;"ILAqjM000Gkq9KkH+;(:*.!c8<1tjH$A=c@Y./ikk)r;ZV*fJ]<(JA$teH/<J04O=0VcRUXfY&Zed]*E(B?4G_2PA9cAUn%U$\j^AJYc1,UA!SkheN.Ve>'Eg"Pfo"+8<H=Fq)Hijb,J@;E\KKOI>`/TB-r(% l2K'E:_Wf;5t!rcUpA%Fr3#5(\+PV0Jl;;Z'+D''@FS%Sr^Pi'=sGE'&;ATs`;GiaSBTjPkdiEce?k/a6+16dKP.?n5h3SX<hbR+Ms>Oa,c@.48=gqN/!sRpJ5G$)J2Y#.8no8d^:fVo\Q30HaWP1+l/]"K.oG;H_4AE,rd]L'G5(:CgAqFsoC:2DtH94<,D\=!CiYV8d0(j9rt-CaR*$#'pL_kZm????VMfoN?tIlB=cJ>HOVH:$]P-1mHoXXZ"I00Wdq5j]E!)&#S9n=%VV67\@B*9?CjlV>AD:J8/o%PG9[lBV'3)!"]%Z-p, -B#[a9MkZNTQ(V>Oh1+L!q6?]jc()`?20W"6I8HA\%4'q9J1S]rAb`Pas.Ts%7lWog6XQ\ *S6dMc,-Rd^C?\@bIFq` 3jO+o,j-29Wp!mN%e3P8_La[A!*UbM+mhJri`a!$#8=\,J.(->;/%$%L<^MRThi"s%oPQ,=?'4\1;SF3b@/$HeC]P&,(^;Sg0V6ZJ<NGL*Q1g/K$?F FF6R0Q1^e]nX3(g08HgECp[HHH*eG;+K>/O%k_qF:H+!q<)b(]3>^VC(@e,FT1l6!j=Q\"rVSSZjR9N]_<\s*@15N#06gt:J%8%4EFbk<e;HkN(H7g7<G?L%R-1Sek()B\\%#E=E>tD1BZWA`RK/l@K43K#1.W:;jQE)cN1Cp@A?@RM;<lHd)q!oq9[W O5UKpC`#88Aja0i.fn">`%>+]5[oDL;N(+Bitm"Vk^6VJB-[rJ#6#GMH*je^)pM).U9lZGQXE?h?jkXoZ .G:T'E<\3#0apXS(#()fj@^0A8l3S"e?r3E/A2]hbSU\Y%JY$<&Zd)"cHs`jNf_8)*K75EGXaG02T4GY42/?X>#HNEHP?]ntgZ'l=I2CTa"TJ#fELgaMTZ@X/0%?s3%c&#Xd"$Zgo[oG?)?TBSoC9^%"\5)4Ccs$l"k(skSq`+C;D9pCgi$PkmfV,sBPInTf[s) #"q=KbP\lE$Et\pfaepfX@<=qHrj1) E!A2W:oFRZUed;2ZF4V9NqmU$>/e$2h]rHJ2bl.1H61)5bZ@H4I/e?T.3cN=YA3<fpigZ"fJ$$!$n&tQ2N:fO'Gi(CHMe0L2H(Q8M"7Q\<#n?gHFi)# Vk+^pp:rfc`cA<l\T_fUFT<P/5+<LMHET\=@SJqE=R@DMj\gjZ51b^=(mNa .:r)YlhTI-/4nnZ^tJ@=LH@SOOAS4.Hq.2 QseF]ZX?R QdN]`TRjeb5p!IUjr(nte;KaZ8Hh=]>qarbFsQY+;Ms_0/m&d$l-.+SaG#GPR0\K/;H/E9S-9llAZ0Ge&3-[X>B3m[^;$r\NlKb=ZgkVl0P?OrNR(F^^NDQgV0\N_K$8h&.1?QAE/ada%f\"NL&VYpfk_Ah%k.g$VrU%15WYcA"bdAKY<KP:fs9a6d<j\XaGI4i,Ui^e,,si>b@*h/<&O5t` 2dUJD@Ai. [nKs:3.U9iKp4ANWJE<Xft@nm/K5opd>MZN8n?CrqG_Cr/q+h#3L%\)HkT6)OP4o([CsG9@L;-0#f8JNGYFc %o]n@IjLJCg>af8B89D0`mmRsTD6QPP'2EUOdV02/23/07NX]dBAC^CHln(7b&DGV4GdSVE>5MT@:g'<(I%E@Eoih:L"D@)2[rg)3@Ctrb'2()Oe1/7MpO"2A!57c_[-A;*]<ab6$hH_FoFW.%r;S>N_"2&;A/k9=!Ha7BYAq+'1(N;t_DA32ml09.J4RXaI4#NK'=8>H2P8g]9g;_#E'H\7R?1'%l3RUl;WT[i>.YkaKU#1IH4?YI,,CLSHVBVr=S@Xk4TA?%K`q#\YjT$Bq:Sb#U;R;%WZANs+Wf/eWHj*.,ZRi>mh7j$[Sn7m8H_&gH+-!e(Z7TLDOqI;pbJYA,aF<Its&KI5Q?;_E@hONF:Pq(rr`smD9UoHEaqdoj7 qm3G(c+P7Qcm[o&:+LC7]p/GXXH80F33??MYp l_8q5s,)VkZeJ?#s)cq(/fAh"g\n`j$jm;afp.&SqD$&]X,EAK^8D[Ag>MX#t*/ASaW#+)o9gr:/]9>XE_es6dO3RUPQC>]HS%)#b_%[Z^g0rm^q5W>[Y424TcF,mi0<'JU3o_eGcqKE%)Vj8+1MM7HFt5.Z2YcZ<f\ieZ*tWeh5POX]M69eib0s`T`VN-g-)Ai3ac8F%qN(+o Mt0:fTXRJXA'X,45k',JrAi_\RB-mVAS 4/a7A'm/ A./Q$bc/0JQIbsR"9&MEdBsH4IopG:mWt!N`-8kbFXdMNB(6?!^ag!hF"&,*oe@?9ttjm9i&DI2a#()7K>?WW4W*m$U@(O1-"imf_%1kgAVHRJ(:GptA!1id\<;'3mV][Q,bqEk%8 L/[KbsDk\h`pirL5\pp/?to+NK=Q= .s[OHR. 3>*\Yt4=6G5&2U1Oqq+bm8dZEH.Qd_Gc)(Ze;&Zn?<R^f<=.mf-Db]q,dKNX;2F5/dde2"'/QQFLe+qDI`#kP;KiWnG !J:r^IAU/Pcr3aPf:0Zr$Gl']d2&VGS;W1&4-!PaKF]B&RZ#c8tQ>:jC(3^2-W6*m*5:GrPS(JE&#MDIL(Td&3nrl-ge87?mtq )"(3$r_JCWcj'VRmd-24+.j3I4&X5fMb[sntUDWci$*K 3U:[]/YZLn08 %hb6GRFRW2U(p56 /Nq-Z]3r81kDG#p+E'T-Hhq$"5G"e)irQd0J9"&QB`ZffD&5!e]$];IfWsQU?gLS+9U08.4XroA+;s?0-k2d2R8`.m/UlS])l7$J)j`1:I-tffj$DSX)t#U;KkO/P'0^o@Sj+MO^lF!tAs<D\^<;A6`-An;39rpZW#02dl`9^4A^s5A3X(UFH@[Bs1D+V[bg2VIfWcb^@Ltj#OP MW[7DmH41Z$0CIpW%j4eU0A3PgqetLjC,=sD)sYWS#Qg&Hgd4j$oG>>m&%XS'RYdC4Z<1_FY'[H".-;[&NP^ ]2nHOm!^RO:V9GEm'8si<nHJf(X$e8+JhD8+U/"^,CsYRf(!P'ZA$mgPZ:#dg=+gB&<mS>fqpcZ>l6Z1OiJkCGse2B!IL7\YP'cJ_6!CEg.J)fCi <5.UfrRlDY'&""3e`O"?sD7e:YrWai>;a_Bn#fZF)#8h_G5$Bisde?Jomn^@o'1>5LO`NbpW6?NJ!S5'iVQqi1862S_)o7><'O+ p4$/d!dZR(.&iplrrV7Kr@Vi ^G8?P8sn)XZ4<T^qU .j6tQ@a'n(%*?Grc[>)1L`^F/K1Q?`'8lA;DLDDmp5VMbpi+7GOd2$:pD<6%AM(Mh0kg?jD?NBSFW,6L&[PXNo$YgY//Ac[2+A7X7R7ZP#1')sAEN]_A2[K:M9h9lVE#\=;+Do&cnCp?3"'S$0YsF!7Dt><V:!X%lT?orUNR)A4#N:Wr'FMKc7_fD(e1g_hkV^'-<cX'9P=H+a'CV=p/?KR]ADqm->Sa_MIp4BAFOHZBni2f$(1jQ1@C#no]N#j)LV*p6MT_)Ze9rF9ql89QBsGj2>3%2<_@#.W(\G+mcm'+[q'*Oc4a%E/A]MSncGaf;B(',QCGP2eL@%7D+g0%!FSLl]]L*.F;o)qZ@63<&F\).cDE<&2e -(5O<;2G8X5e[j:U]G-5U.WM)5#40mQAUSr)E":a*l7I&W[@*ZlT1ES<N^/Es:#1K"&\+SA@Z=nK.1"Gij5<9$]Kfdf0UHC-!k*_Z;Gjg=V>J3OQZ1@1cL*Ac<]MJd<hGM;pl6A]T\\bX7( Lj',)2ttD'qk!Pk9D:i^GOp`)eUE.KKsD)H]cBi5YJh<itnm&TS2d(/jQLQ+d*DRNs$!LanT  P"$'A R]pOo-3I/#?CC4GPR5GJsO0ijDn8g97>+%.USp+(=CAcI)_hnADV^s-GW6Fm+r,?$S28i^PJ'GsY<>)7<+b$PWq c'jtT#nr#AXVBFX,pcM`%OeGKWT7/!SqaqH9@X57F#JI*FKA_/1:*s&H#XO;-sOOS&G0i`]P"^1jo5W6>$%Bs:HgZ.9,WK3DcQ`W,aP+4:s5AWjM35_1)dks,7`f-VJOsE;D:c)H=7FZ/VC,t'csDfF%/Fp*T<ZFj?a(oN^hn:]s)#:OGSs*$2S$;,>?@ie*VKUWkGTsa<9Ud,l;kR>/7jjs-eH4^j=VF.l@Tl7a,ApLb<HTN>j,?PmL*t37#R)TVNE>9'LjZl^+@ha;WR'X9FjOU*Ot?k+#YE:7G>nW+<AT'8p!TUpZ,+]V>rDPR(L9MJY>ap?'1 A\EZK$bliYn&5&oT<Yl>P!D!K%BS[U!j;b0pY2 L*gBC<m%C\(L=IkV756`'1SsB(H!-k3 *5Cp_??X"'pC+0rtdLQ*BSAV@Bt[tcP?DWT5b9M9X&04:dj]&+9"Z*Y](68fF-,%BL5#V6tDV%:U!+r#q<#KG?*j,nJD\i[d/hM)>lCjlt*&<1Ko`FXB\:*ZbD]9K#`-YKZ&+g5h)F/^=97iE!ApL^rdR?1".l(e)t!h<0lg^;6!4@#1jn\Q<^$LBt\;  8`9V<`g4LC(so`<% sAY*a.P'Y=M>q-C?;k!?knDk!pZ%%$5K`XW,b8H1k9,)sEbWjs4*AC;!&H6fafG:Al,0c,eWQ4>,lDnFSf.DK;*`F7`b$WmhO_ZdOa01Uo#A?,RVD=,@H-%;/\CBD/-Jb")HH!(0XgSnIhK[%b5-/h^?Wq0Q'n!d.NHig]\K`5c"X^b"h&t,Pg- W"[X(gqPQF4W/$GtB;%AJ6[#VaHTgV8HNNV2^rKR%R_"MU:Y+-Ms4nB,1#ArtADMSY=\dYXe<h>Q])g\M!2cJg#SPCHqh711ObJk&HV"qQ^od<LfK@:FV'm;$t^k:qE>*Jh2f/+m9;\Q"@IG$0JE/Sis9XS_2T!;K [nL+VWJG!s0&:@klHsX@(f*4R/`sPYR'>8og.[LK-Bb cq+Zt6JFbdaM\n;o,ohqe<mOA$3@5dfO-)pI,e#[QOo.k"Wl2h[Q'jk0[:4p!LVWA.+l\,1cRTL.oogstQ#6:.1=.4)9q92c1]LcaJ-K'n=W!^^Mpg`5/<(6>1r 2p&'i)&bEGE.ftQfZIsRh\C4H=>3M]d5@c+3?F`]MNZeKh:/[(JWbXNa]q`?F4jl8OJEQFI\>#B-t1r?1m_[I= 5:BHcP@3$d+aG"8;Mg#TL4.lT2A"pmGo@a"&nbID9)DCW_SVJeZBCClsPG/03gddPG7D@!A\Y&j5s93d:6kT'LX$Yt7gEP_L?(p.#r=*b-'sc@SE6F[(>4nn(ZoC<8AJ*k@(Ua(mCNt,N@b>qm,o^LQ9W&V^9A5I%Qh;RJ\E+\BQ%IoG(!3GO>l>CAi(a%mmB*\4V9(lAI2J%?7dS^3/b0--0g25foi="!]`r3B`ist5eWDsqF'GNI9q%#TmbQf.L#ReE<pcfAT,ODsQ[38^4 dQC[NUX3P9ZeL!J]asH>ont*o+oebK/OH=B+;*tiAsbQsnUFeLIQ?j]kr1rjM2TWiEbkmP1]eKPmR9/A]t!Te=W<JgQ4Q0/b`'Z2dTo?)_"hmsS0EXLo; Y98sYA;nh[NAKRd;0gbtB/A43^d6"IoRjt;5&j>>9A57.dQP^mn2Vob'5jY,5orT*p5*`'@'^GEG[C`A-saa<Y)pjZ"O++=,Y?BH_sB-[>a#cQUo^#>i+4H6<B!1QeG]PBn;8jSNcNlROM#Q2VJGS)E\":::,=0,SBCbO6QMNB.6FlAD"Bc!&H]M=f/>tEkHi4@6(]#W.HQT0FQ0IL%=-(!r9^!k2MWXTN-dt^BU/'"0f4tZ>gQ^4/6>3:kb!8h <NN2@l!ke8s,L*i$bemn\bX?h7&Hl(1ZC>gZ#`[kD7QBPK8AH9/loBF`d+&(.72#=JC!egf 95%>9#IF]0.T-&Y%IUD+tLR1:C\&R!rZ9Uf2>LjOMn%Xn; YMQ5C[f(UhZ3nAb,CO7LW7$^!o,bB5VRhSt"i4i::S=7J5X[ .Rp!-E5#FQN;+qI]7,R(:SX1%qCWK,m\9="cesMOMHp$pS1T0 \C^,?Jt;_Mm4]=i1X<C/\!][_>CD!spSN?1KInk`qiFiWF.]NS(HN]_bh:VgO7'\etNMBrm,/4>&o`W+tf4 -FUmm5\r3[ALm9[dUJ').^8);Y^`3P'A^iVS<t ^r_.4hA5Gb3L"oK2-X0CK?l0&@(O\_RZ+@__a_MCgFHIh>jaXGN/sQhOITrQaU"p&6?$4!q6CE)>Glm2pGe-)AX@4V,XDT $`)7npm8=e%*!>2FF^aXQYV_[2d5C7I_-[j]DE^\J#Q&AMW!$W]G3+N,.\?h>%o0s0o\gqVHL:%N]iL=]9,j(m/Ap5moYVK^T"Sc(\^qk1pe33N=`j(<*V:b,(#h;6rS8iq1A)RBW@!G7O&V]l9?B;Mm+8<-fWe]Zo5d%VXW\h9a4%4o`NKq0B/n<Qqg>]i1@%9GQ^2^Q5k*.$=LJQ8kXREg(8RK8c#.^FYVT@_$.N,j'sOiLfPX4ePXH;)c3jd-[9Te2f;dqhqs=S1Xcl&KmS%I(;Nrp,*7Z58NA/4OXlQ?[%3.2co(`#KCT;3SJejOR')!?]^^1^-UYY/.8 823gU]>h=#BjfAn=*&mDcSKpPsL(G4KgA.5%@acdimWp?ef:eiQ*@X)Z)MZ-pe72V)P]e l-A!=/Z<%80KA5*$0F@:Tt%qDNs4^e.Z]CFA^S"JhaB7r?A-n=otK*Vi#)<58lo/R4l).aDAeLSFsno`1Z#P3t2GC3FAal78/hoK,>'/'Z>h`:8[-`^7G-#Q7d.Vp.O^b-\#E:q86[UP@32gn-R4$-dN'48YiPh=Wj/H.K[^>0e],)7j6tnNq=G9(lHZd=*24"@WP!\.rC_R3V>W f0CF;SKZTE1ZgZc?$p&`.eE]:5^?<`]T")RtQJiXFI%U$Y]+cc[ 33SM^_RGC<;&B^XnoL>"4g)6RaHjX:)!P%EA_91FCViV<?f`Mp+$9Q'@=01Ct*#SLa.Nm3aJ#E/iHq1+[%F0!VN91T[02@_*^D^ng:#qUmANIgE7S)_,@0RGs^n$asRjL"/[_dQ;WB(D@i]m0lDbUF4HEd4pkdbEO-I@W&S0#J-G;R%`S-!BSR3'MP*H(Y]#kOg_4<>7)"lR3HYXWpet\#r>+f`X&g[tAHI9iZ+RB*!4/jP:Wn?`*A5Y$b!eWe_[Z$M\<`@OQm4&(RWRNg4<Q-K5Xk67/??eG+CsL^`(#GWOqedc:](f HK9J\R>@k^D(KhZ.*?K#=On8L5sGd?::5C67$Aa[.t)9S\1"(id(R)-O5 GIcCO;05;l4;MQ4)K^-i;UHS ^Y2]!ac8r=K9#i0(YVENL_>WO`dk'?[m0AQOSqX_UDGWBkhS,.@W)J6s0aAdj3Tk>I' $ghFc!V[+,SS!:sAIg*lao;?1Ule(YLR*M5hgS0sRY-ULD%8"6"Y*CFA(V6hW%KE\=V2D%:,63r^g08WZV:OD'?-pdNq7Xs i$aSa^,'saNZ.?M+g!YO(Qs]>N?IUY?TSA)=5QmS!@%U6W!MQ#Q3rS[tnb._ab&BM,OnhAE$QlJXT*H3MH$jKa.1sV+aEY5p:[5LgFE[+n01)l/B6iA'4kB6NV!#.,^LAK]r9Yi?mG?VoM9RkW6j96cnWCLG`4EGS+b)'_!4tAfYJN)H,'[:^'7G02\eEZVFkL^b1C5V<N/QILA0JP4N5e7[lRZ!jLY4#!>W5%-HC5 Rb8"E%5!fJ#@l51_4a+j>&\36@h;AW;GpNcg)QVBS:SJn.CE*(5p'FqT_fe$8=ILSaA]KqU-'S-51i*AQU5d\m<5'VZt_nJFYYPa$h1N<aOY7$A=DAQ`pQ>WY^[2Pn8rm[^A$K5!86p8g@_m@i6oAIE4ScABg2^@1#5c&V$G%b6qXMEWFP=hZ1I4@2,Z9OE6AjkPDrgAWXS!Qk]M<*%H0ck/5Q\[B/%)R`\]%?/8K-\VM3NF$W1s@Dp=6+bk#H2KV`b989I@RUiQ2[\5LJkcA#MD/ah$-g4GFC2&/>F][OmO0nT'ATVfl+JtK?5OeOlmXOsmW_]2:a-*#!EDefH(RA&d3hBVH51b`JNNcZjFmZW8LhhCfRdsX_;[LPk0^Amr'Y]MaFM>&"Ah@5oag&U>0sgOh4mqCk96t-5CDAAIrtBjMt6!'K(j/!Y (h/'9m3N8:?B".D<&37kX3Vd?kdMId!r2N VO :#/M9pebF+)s8_`k-jZ KhD<2Qi; ]"&.X8Yh=`_iN84L^>.,okJOs#e\:V9)_As;W7&fsW\9M9A?bpeq4[BAJj)^GanF;dRBATt!MoskAbDbjmkS7)(,J#<3n-$hfAM lP\F0Go-'khS`KU^>%d>-ROR%t?Jst90nsR3`9OO+mE6X\japPR"54,(bhMjc$";$h-e_H5=tp,[YicH^1Y`<AXO_"0M`/Mda?f4A2.oYt0CKf]+2D$h@C<>#K5%o%)D>QD:  scf`r2dgX">cHlTH:>O@ZHq=r1MS^$gGN'Q'_MHD5n%7m9At6WGIAXS'%V*C%I(Hc@=aKUe]sWo LZG9-<nfnSKC.$E-4H RAi9N)C]jMJ]]n713<10-g^4@GNOiKK'M;3dM%Zgns9dALe!S_;b-N7\_V6-b ]Z:=+idPs8X.[G/6NRd/i$760^(&)m8U:sq/4TX#[Xf(<Oc[[%aip8`-\7$[o[(]V]AKF[4"T*h#4KapX^t(X(<?A./%YC)@F66Q&R<U7kl"G;"OCU:G;5bYh(Y31:N=F\]eaJBW0&'U3t3N+=b$$4Q*i`%Q?GA6Q qf0#0,: blqbON(T+J0$D<aD?;-%#`'Qc+bh.7ppWMO@a#^$l^+#Jq[B7"kYcrpXURd#0tV!KA^@bn@'!nEW=i&o .-Hm[.B:Y&q:dT+Jd)4!/:Hqa1R;P"q- s/a8#:BWc$^ VO2_\aXPY/p[<@oIPZ.m_&A+>?USAg,kG:bZNZ\<GShNa<t)&ROnCA1S )RZ4@VQ<`6'(RA>Q2Z@-aM^l5CFCQKa%(M=APehR>Q;-8-0P/!-'q 3#apC":a*D'E*a9[*!Q^"l-Bf=@@Llb6AtdX@D]E)T@rUe^+CUqm:o'']Tc>hSVnI0*mTmJ@r5`k9@Fk`R)2 ?`!FIV[Km(<W:a`+GdRnS^/q]o<>Ps)aAdN?*,Qk!,[^72@"0Fc!?'pr2jVr;W,Sc6>C*Ttp33,+@[p,/0^N]>b")p*3^c:p1UULHW'`Be"Q]%:>>!lJb:/f`j-Gisba?UA#G)FA^tE[=KQFMt-s-NVI\03s>h;`@E-D6t_6L @ Hq(Yf[.O(@;"<em,i[#LGKDo>R2i)7l/>4_`_NaT19i26)Jr_+d_$s X:\&;O%@[( :%Z-,$!9Ee@r5MHL6G8&?^!Adb]e@oD+9ghjPrk8-A&1KfVNA+1Yf1;04dqhb-<>5[#LJU#;t1K/!e;]$c_eMG0s+F%Y'6$A/5GJ;U])jA/JK4Si03G$`^7<RL&jVLMFT<-ZXTDbDX3ld1)J1Cbhh^/B\_ErP#'X)h#l2f4M6tND7o2H I1,[N6(Tp3Z=eZOL(CjFp$:kqAnLJ9,LGG>A0J@g10a;Z*B3IjG4@@R$G&oYI0W=!m6CaZ96WZSC7"=QM=FKpoGA)m`Md7:.amAMa5BToXgk@PAYXElF[]A@U\>AAU]t>MALHRkqRZ<(*o8coNQks[i(rlXl1>/#Nn2`GSaAE=ab>6Rt_` +=p'e9f#9QVU[#UgLV7IM*&6lRf8(.'-DNK>ZTA;/hkV`1&k+A8n9!6JO(3fb_;O3.[ QX4+o^09RMK0-'bi']\J\g+#04UmYei)g]%=#-ZG&PYQbY34(8D$6Q!PKT$+U2CrpR"[K6,\XAL'El-h&TJ%VJ'-qsL=qVdGNJo`V0bn[)oeX7S"qqLl50T=h*(d]Y<Y8VSSdiF5RH('QbC$Bf=O"D67NT7305XY\ h:D3X,]a0/V\MCg7T)g1dsbWM0GtOtk,;$3+aorA_K?1fY$qajObBWn#$1s?ht@SKDj"mt5niIY 3Y-o/CU)9sWM]_G.8pk?P"3S:B<@$PdEFpqD;#,+:T[K7"'ABO%bFMoe)8H!AK]$$)ljk)'pMCI=)J'mo!5>o@@C)+)(6QDJ_[O&I=[:(O6ABIPAg"jFg+gm0=kl,GMtT<#L@<Q]7Dr\'SEZo> !sjU%S85O.iG`1SptR!Bks[AQ':h,\FM_#p69ZCI:VR6M1M/?ASYkm \ng;kEZ"<+31"U@(`*ar^?jd&M5Aie`T.RNs2$H;0BZqep.33K $CsM-4)9Af16*)TE>rZ+5b0;-"' &edIKN(`N7A8)8qsrW>)_s%d4f3o)lsG9jMBG ;1nS^#QE#YkA?,R6R>JfK=%&j]0*(&6p3icNN$h.:P1_t=!00#0l!SXlAPP?>03)\99)GUBkPlAWf`6&?@!l.BZqq8D n6sCeXg%M:EK2`%m1C$_kF+PW%IS@.%9s/CF(Og_:hT5 MJR6W<-:S99' d!:PgHA=.RG6-bUAcd1.5eY7&g]Ca1,;U?XLD]J)\l\rkG=Q4ML#9;HD$> i:;On'i:k4G:%F_6i[FG'2V<>k?^b6.lF;leO!G<Z-8O#6C._b409et0Kj5+R'>N>`T]$\mH.J9*mdF^0kNC:24 !5(S<Yp-EAT\_FUF(H n0ZD*M#Z' /.kCt)0V7Z/c]O3Uc&s:3r9hrb;Z,1@i]1SXUBH31IG0TC*=j!LiqoAPG;seVIL,qk`!TUl6f`n=R]YGQA>@X[AJ7 Q2h[K:1^Ab*J"56tm<F/d)&@'B/5l_TWcaVrsH@:fBV ?@,k*A[A$;=.%cI/LjP`%q2ERL,Y&"MX&tP"PP]H7M]Sq92W1r4A>B%7$Rln"q&[h&=,BYh_At:?asAr#-fM)n]lK@%lA)h=%.%-X+LM8b=K9`6&<oH-4n=2MKM.GK,2-<i:#U3cl$9`$j?go'q<H1PirCsT]NA"&O!@./N\S71$T?<Gg@Z[pLsh6fn/46s?PZGT&  sVC/ln3O'Y@ Cq3jnT,3RP^+UQVLUWcL,mQhb2CMk?X3dHB$W4$0:,e89_Ith/_BH!!e_+BZVLE_CaN(%+#)2TTG'XgiVDP78AX*qS]'XFs"_Cs.lJp%J.7)dI?MIQHhBI#!]`cW-*bXoR[Z%d^/;3p! Rkhk:h70^!LF>;$0<iZm8b@KX)5^%hN2fC6'"Hs+e2ij=`;RHdXch*aMf*;;X-Fs$_)C$+*Gbb5rYOtpcOX0("e=j[O$D4P[Z=) q?4;)&l]I; B,=gj=/DlS(7tBs(a\dlM6E=[" A&/G^`")L*M^Gt=m"/CSJkht5$eY4I/(Ar+-gAqSD9Er<o8r;hYj#@rA:H*W@SAi-ApE-;K.V&Sc;LC?1Tq[0%@Aagb11@</ lQ0_2aaXcQf?0aT,;Y$iqdWe`>D,5X$QHS`hNP3m9tZN=s#:5kd6!Tc=&LW7br/$?6YN@L0E4h/Y&:DeAB64,D!osg%\Ij0A W(0A:QVGh*ne^n$m%K0tPW969Gqf85jH[*=2;8V%gpHV3KH'bqZj#i]QImc!'!rKVP5AP6l1K9^T:&DmQla*='?X1SgmA>;@'>K!n7mL%]]L+L_)NE*c36S6pRk.&P,#AFhISXq1d:(E@)ltEIq2Ik&KN[.<r%g]Q\-FiNh/1'$/EfYT1P5n=#9[AEJZK;pMZ$D<gj;F[!q^MOT\MIjM9JWkR8Qt0(4flaaE.t\Or^!pR*hS?AP(IG-H--$XOm?TE<H7V_UWJA@aEX`I3'H)@b!#obCq`4b!8_XIMlshUMAW*R'+,M9mfI)jF[1H"dA^AJM]#fXN$Af3F6"a9]`.!FW8h<gk;nliho6mfgYmBs`(r=@9Bl%&/STZhMnNkqA4jX=LjB5aN;a:(pU[@e>Ln(AH\qqX/[87\(P]rM3Q[F 8hE:![%M/*2V3U.Ncn$8eT20-@NA*RNt%p_-"W]/fsC(Nop\Am"f.VW[0,jQfLCPm#XBBE2U^sV]<H9&NTO0^gG8 M$'Lb2XLO,+Lc7+pgAVV\NO/=@:$5ACqg3$_krG^q:(KJ;bRD-[`/`$%P,ipR*5Ns+f@SdO?o41O6gPbKd33[NQH%;0S;d(-R@ P<_;.> GasoT^9Q (HDl.MMKbU,fNR>.[N28U;d>Q<NcS*c!1Aka&Y@rX0abd\tHKDEVgKo5dBfS#qgsSll_;)EFE.c(/0s+?<0,m^76Keqie5]oH(KXX6NsbAlBUleIO?J6?a,$:j$!j6"HNP&$K\o\AfDK1\F@Ie,"AdK7=Jg16bo*#^KIm$`A],19K@*J3_b.j:Db 1 QAn<Lg-ADSI12S;,7F,EX#/b/D(',e8=sCVAP)nVQX2(Z2o5K<g"Kj1]I4A6[d7M+!*_gP@gog$X7e*3:2h'gMc3K;0>Heeg?RrMJ5diRlXW4OdOO'Y<sO33AnBs2ldD1]`67W _`^/#+5(aC4YCA@lh?& ^``Ab<kk=apN&1l!:1YgajhalDN)Ek>SL[Tj0KE2k1A;g,+3da@N>X&iR*DVB$hgOrB.0q%iA[/LU!#f-s.1gh/nd,8cK<B0p-.p')jE[X`VR6-2V9*0":](e<g6fHl76l[9+TFDN5P=t;Qk?(tl^XccUe)QT'4^51$*NRh#iW@OC>*6!p7sFhgmi0a*q-g(t]^eOQCrO"-[SH0#0o0Z^pJZXOO`Z9EaV`C?^m#Iog#sYVgm-hfNIBGUR3tebZtKE'aN#Mr<QcE@'<M_<Q/Lr"oCL&>Qo6<1k,s(8#k-p4spe`o#\eUG?<n0!i@$F]M#.N.AVCZ.],UR--X-C`,@C"PUjhK(Q0N[T3k]79*lSX;DFl >- .;tNl>H9tlP)mr3Z$!'o+jX95fDM[t2"1G?ADrG9j7EM0<l/R1G]jl!>,;WB-FpEm$sE[&"::Pnqq3/@H(,bW,f/KJZimq<PPgt_AK\bmbD&DVao2:fV$Bdk3t.K5N\&h:?=sh33e\R2b=9lFS.P10#K.k(VeKncUo%/:m[L3f+)&8,fcf_k<9R[*K=[Q<nX,^UYSeUOG1dTB2,)-ne.LXMrB9#N<smqQ),mFIpR`gC6ct73F)hpY8N.bhVGhfXb&DJR9b-[" \sg`Dqf4a`mH7c1em3m<1Pl4KX9_`cg)b8jcVAXDIQ]dtH<`3^n\?M?,e)]P+RV4`A*CAN*tdEE2^ffnrZgAKXb"'@K'J dX?)Ka 2.>(WYlJ"eRMO`TXOpSYM6-Ob&d6S+Sf&+!Yg]4+A=qH5S)3d7*\mdiP?Amt?[ANU>OW#L8teRfSZ[^67<[f: _tX'AEHnAE[W.oCg8a$Pt_g`'hUe9L]R)93.*,M<X0R&t@#q\qkOhcn23?on@ZHTU-;\qS@%<;P:?h>W!-2]Z`.hh(;BT)2V/2m(LY&)<Kr;3*d5[DL&?fV[n-OCocEE;@Gs'd_.%,sI__2VpRl*CpYCnVl0l7O4V["'L><[1I">#]<<LW]%L?,[pOC<!` JKt*S65UOW;AVD#.KbR[<q!D&>[nSVMi+"9Nf1>_(KKoG<m^A[ATiW!kZ)F+$1Hoj`EBRBOaE;T>9mT&s&_k\g7%o,qZJDOtRAl[#@\AI&^*<VAE49^JjXON0(7pqP%`,!Pbo>fm!No$e7*4r+i^E^T<k>s/=osO'Q.<t')"5*1/D3Ng+c!^PeoFI?PIX'k1!?]NeMC#AGT"GqEZBf'HB2U)?#j<$%WZcl389349(Rin)]>`OSr_Y,L0TdQO!Gt#A)+2t^X?Li6\p+PB-4A(eI4$G<G2KGQCFMGB`8ae;T.@a?S>BrC47;&FdG2AB.#Mf-_fP#W@ro;\jcEr0/ct12[+N%<TWbK ,n &m!ZBKtjXU]f?C7\lVc[Q/PRQD#jDUU6<\@9Do%9S'n1cC3E#<*&^lW:VMc7%mA>="D"UF\qhD3nJCm ptMaZ!-bS2:;0P>&[T]k]a$b-3XT\-'P=KL]A%Xh70nX:Uaff`i#Pgf,edW'_GKg<gcCaiTOTpt/Te5T81ALM\++"$7jOIBZ@GZ@J1@d_UKg0o?[&'U:Y@4D")CUMik)6'Ob="2E@5\8mOs;$4SB/49L+hD)J;m_dSZl0.JB`=tM^bg4m?VN.n5o&bh@hR1&.2LP$Lb?gRk "c?"[gQ/f(d+tJO9O flH_$\84^ +T&5TFSD9B#ae>7)g5gYt_,9\L]>go,jr!tgjAOlRTI"3DnSX(mtXKlKgA9bD35!>>*1_6/"@)NkVS%mKFfHmqZ7`.LBR;,p=_Q^D63lt\Z("HjpNb\4^0<m%JoPS:ST9?D9YciCmG2iS5Zg<02U*Ai?nLJ76">-<L9\PU Pk?V7NZ'd]t-AZ'dlO+>U0cth)+ZG"<2g;Xc.n]L$btADVq.e"VWSL1rV>=4C=0;o8:9to5FBNO,nAm^Dh3fR1j,!M2*\*;0e(C_i,km\PAn/fJ_^5nfOMk<WIBXL);:7L3SGnnT5S]U%jo"U-,@kPHO$HN]/q:QQ:2X\Y[VBACe&4[=*FT+)Q,Vsb`6obVQ*$r$[@t-p?"I !6g6aJ% `Z@4Goep^#q!_]F?P%>8=>,d;!ZB(#TKmVTo>;U\Ckq5Y>[/b-JPf7L@tL#d6'&NBV)f],\5I-S:#ASCGF!XI3BH^=breg"m8lAAbV0k_BSC2BZQ:U5"C0Jo1GGd`1gTH&N,IhHff.UnfZTB_WfS2Zn.Gqlnj7sZS?L%R_S8m+P)f#BZ,.]jj9;Al#9I";l:4Z2-IMIZl\]4KFmiq=(t1N&BA8L[H0r[Wl; ++?AU3o.A6T)cjD()7_99M"mVd.S#"LIoicsog^EW&k?V*X_Y?j-)4AT?Jr^58IJ:!p2G/q;iNrQXTMOF=JOBfL:ZBlh"L0"PTK5Q`1p\sK0Ne9Jn[I@ P&/e<:,>J<j%XEU<-@Xbc:f(qMJ 1BQFad,.,p44t5/5r)Vq=c5(>!0k0iVd( -oVhY$&PS(>6#6D<Lr(322AeR`1Z*?O7WNHJW&_CHKa<5*h9@tn$GWmW1 F*:'A`,%sni`_trc;RL-M0soZs9N1oo7X%'D;G$;AeTt(5dm96<24-35clAp1</D+DBm6`#n>0R?@"/G;cdJJZ'kpIYjE0^W;XF)@6)ebFR5 D$<WN,Fch3(1j? <0DW?a674XLcm/TTJkg(ScO[?2nlkA6iin !4D"iL!/W.>i_h?4'XgH)kK9].eX,I+<KN?b#7CWVi/8a4R/a(4n>d 5@IUTA#m/_>^LdkKsCGg:6%?`CO-*2AhY=cAfQE:jq/LUfKS%Oe_%Ac2571+OS^:q\+JMM#DTiK$?qs2qAD?fp6Q'!4H*<07)Q`Qq/1++o)VCNW ";j<S&+-[ois:kC)MW,Ba'35Yoh1hR#"JlLPpPTXZ@Mr:fW:<S[T)tin[%D6V*KYcI=!;Y]AKQ&o]%Hl(s(E*6A#q@%S8Wdt]Ff\q9p6FEa\^GSZQ dSk`aRn!` :,\='EGl/n[+,6BK3J9OZWbV'q9&1'3;FmW`QK'?%mGGOIkX]F6\jDnTN!n=:2WnA%$?J]#P(@M97go#PRJI<sj3/aQqmt$Hi!!qKr6;?`3XP0bek6AK=q\$I,&^sNafelHaHCA]U?rX8)'P2qYUC:#I7>PMcajPaiR,"+a_3$A%YA]j5SdVR**sM9K!(V/G!#>0_l/:*MEAiXIPP&bs6%ea@Z=[;l`TqM1!o+<ca09%AQA dOF:LBY.8W=lki`rAUP0!<bk[LLFREC9P!dq`(=$lVl=Ct\Z$'lHT`EADl)FZDG('S/NZ4J#+<W5t3' VakY/I9^0;R?cc`qQdq*?C9R+3YfPmG_3;O.3QSPA2'q-8HL(m"RgelV)RW@H2!3ZrmX3h0d$<*Yq_P(sD:i,NftXn^C90g9BR!P\)&qNYte7U^BNWS;D6/15o&qtTG-H&bfsc2[oDAV\5N5RKA&[[>7mHg-YD?3m%1GS00r<P5t_Y3+jVHRR-*RLOCFA:="StiBqqsoI0fGl!CV]PeACc.%SA"gn%jmS/Fmiqq&3=X!NUBc]E%k!5nZaJ)VVX;9B+pI2fO7Fk!"Afkr05Bg&-_A<J9DYp'o8`oHdc;>;IIc<NalI7=M'^EXK Dc&\Q"P \29;7n1G`QS6=n].\*o1t(,">QW1EAK83'=;% a.Q8sA.fk2.Qcdm`,g=$CbdABJ)[&F*n')mgl`Hst,f?QW"`rU(a9([[\2Ikeb&,_"i_"r!E5\rhS6>^EK@J'=L"Lk\"A,VSWrSAki;r<'_nj>'B4%O*TQo<CR6.RE .0IUP_ngW5TZoJ]1dIAFPpgq.m)3Sm,T/j)kVtaIA7DDeF09<\^g1HsjB3jQ!3o+M$:I#"$Y)mBBNJo#Ks#],Yo4AW,l4F1rIegpDd,R<Dd<+R]d.^aApA^WoV,H(DCGGIU$II,4(A5fP;VVbG$C(Yr4$/3ic,QRIZQV`ak,"Rf_N0r))A0T)nAVr#`t$U7l&RdH,pG8g+$L#q_ 'bjF!j<s%^s$_6sII<2)F*`C=LJUsAq"rZC8%'?$DnS%Uj@Q!T*N60URM'o"ZGssBF\@aiQJpc)CM5cgc)O6Sih<!:g<7:gFgTA2bS .')se-8*&EA_ r.l&[0S/XJ\as=/KfV60Ai%,2!O@S5dF@*>1D<"\8 A J;Db)5VXGp.JEDoU&cCGK8:DqAh'DJ-@Q@9QmL9"3Vb6-P!IVl_aXc<WJ@K?a$.4=;K]6t5sE&ePgVc"+6(Wa?1W]]Q?,0/,l\AAA'$XK2,FZ(;ORP5jJ`<I+c9#A`RAKi\Y W9&Z&Ck[XP:[pf3'1Ls]#ALd.C7c nQG" >_Y`6,d<g2L/2j9ZCN@3Rg?UXpDCot0O$Dhnc6P.RX(e.#4_c>4W1#9P-[O^$-$XpP3a5TP9QapQA.3Y,>S\9VE-s%!'-:J3[>@E&RU!B^l`5[/]5NF#E)KN3iJDVli&(^APc=W;C\ts_-A DQI1G&DRaQ["gUk'[.-qf<_?7:DTEOcsA"WZVI!1DA?6jC*3"KF1dik<9ZsM!*!sIW9A]?1A3H<dr8t,XqXSo$;"tT2btf;pV#F $mi@U_#S!/F*)k1_.j090<s2%C gW+THP=kikhtj*?4nO(^_,-jl :[lbl_SlAHn]Xe[A*bGOM>`Ggn."5\R"m^cEO0nP`UXAT^:r@A=GtfQsYK QCrXn=HkrAMhY24e-qFNG/N(E?tFiAS>++fFKXh_MKkGI$_#BhA]fm7W7nL4b-3>dsLfceR=.-644QJa@%SREh[fB%lQ L2203F:Z[re0bL*j_M<nstP<:#;\VKQGLs'U:K]h&N[Vb4kQ&UYN,-D.[0S_cUkC4G1f70%nI%T&[rTG`WL'E`j:Tk.>qpjB.=$=)1F6rVgEehOOA?,8Q/AL@^'f.=D&;AFKtF1!qa38E_e4EY.Ul/.qMA-^'-L;nZ2+k<Pt&-M8'1HpRR De9',k/MIA?q;n:qXk!5bNdlG;"YX@G20Q.(djFLeZR@F)_\9*_BCp.i6smQsIXE>_!s-*Z\f?P&D9e`+T?U;X%EpP)+m_e`WaKK*S:f%.L[9Fsng43neJVmSA5VhlEhYV<4Qk/0$?7?!OIH7/%T+k;h.d?e;,Hp,FMVjL*]ZBAjbHL8e<:)#m HZC<]:3D\!gsl P%%k+#`ep.P@V8@FE;89DnX/oW*/Qleh*]5O=#eQ,h)6^XMds1%Sc?s*DXTj/F" cJ=\WI%pj;dpFa2Dbs0!g-JcCql!(t61`Lgg s3U-4*:f)@SG&dS.P5i$9[T/^ATKIBllJS$Z9-_!Y7[/`<Ao\GJT>QWbd]X9K274$"[1K.<(j;7 h=::Sm_hEn>l;kaZAnVtEV/C*f^n&At1FDY4nqJ=f=( Jnro]cA&UqH`M+Id@9h7ABJ)2&6%@#bbRJG5reK9l3ndDB]KoBnB;)/t 7QPTpk@6g(?q,eF'"rBXXI_-LqfA/cYARq0Ot?ANt95D3*f>1e'#2o*D^->`HJ(@q5E ZE%&hM'okp0R\*\MAAMoAMje-0SAU)%$\&bJ]49!njTfPEA*?AS`%2ecd)A>j'@S(Sl<W?$G-\e>8:@@?!]`;6o,$k#J,LI`T?.; DaUU9)#^nCkr,-I'/*g>QJ:O<!$Mp0#,ZU6jADjA+_#&8AT'nH pZ,:c`nBrO\QC+E4qCkZ.QgY530>l% [<1KRqcj"TD\'O&Y2<%X0(Am=7o#VXg[h9Y"@1tV5&#@--Sr.(QU.0nf]P,4MRAl7\_H7-f0 \M/l.UUg\t/jI:'Zs!r'a%^o[k8*/hA0g&Ht6L(^A6Z*l2HK$1*PAZCN5fM(G^nT\V^O";<Rt404c #tp_FVs^LleG+8!(Cn=qX<_Uk0"UClC%'`m@PrpI6jjGbBcrj9qN!#\"TWdoI-S83tjGV7B7?G8l<M:eId1JITBn\o9`$K!#/iAFG4GA/?a$`Ai'G,<7_C_fRWq`CK0S1;8IZ2OsS(?L%dABGaJ4-H'gOAB%OiiD,?0RT,cH%!tRnL2RULg(ab^X^Lg'LYXXo-'I":3*\L38B;BZH4D.Kjb`T,1$!(.3nD&geq>oobZb>;#1WeTQdB;9%t%E9PtXBsN'QkjAi_CK<1*do1HS$lVpatOaAWH4<pgIt]>`.*)7mP%gFIAo:A37TFF?Deh)B-PF)QP<'8p>A-D)\GLG+o_>+O*YepW=P[b]n++Sbn)0J?@ehKoD?VSmHiK++E\;$,#?,j#Ks2a!c3_R=K-DJ7.N,8aJ(gIfsX3c2)r]W)=@e:!-CDW`AEM-UBa7/MCc\GVGa"C+pN=B6Tc)b-jcR)?`?ljG1'4XU/7j#qFqg8><qtKJnQ0f%JsU=-b)&P>@MmXD;,%mni&W6U-9%.#A#J1)j6S:qe:7HNrN9f00@"=@g+o'=bA(LB(#M2Q0#(15*,#hI=0ei7nsbYW?rl0Jh2_'m9.CLpb2f^DLI4'h;kDoen2D%[njMd*]Brq',GS%4Ti'&lri]L[^1,llHKBI#LA_]"5F,^ .G&,@/ATTj67<&QA;A\[C5bKT>p$*d"-I?X+RFd=Pcm8WOk-O(+j[0inG64`nWU)>UX2K+8r9]8s)NXL'5L)Tkn/i>P\UKVb H-#/$Rk`J%S<Psi0%O-NnsM1Oji&rEJ AH8Ie*Anj;:/?aPA?,q+"rGam:f^@#Yb>ma#PO/=H+gBY"1PWQ]-$?O/Xn"k09lk-i+t$&aEV!:tgY?5>k?Q"f9#HmnZK!Tt$5Yck7V3c?ngJ7sn4L8'kW[U7CVAjhCb`F/Q<RU*3?kSQO83c!G]=76=C6OENoL"J>q/6rP6-eIQ[RNfOihrr%[ta3RXVhh2Nj4A2Wd&<;sYQZXpo+4Qgaocf]b 34B;59\?%Zp_8TBbO/`4g2lAm'H/2%9/;eP<peJ]:)M'fXA(+Eg^cAU/Js6CN_!+1a'\8nW=XQ6T%"^)&U >-0.U`[,SOYJ:SVE][itH,RW"PbZ!MgHV4%[&-9LQS^O\C?B_YL%W r1/\2l`r5r-eTKc7:jRFI[3k(Bdbk5$3E'NGeg#!Y),<%'`Q+$Zh>N! ?K0:2:H`P`H1mq9kG+',b]^`-TJ6!VDE kXq7ODPC'db<HTc8Y \?'3<nWDGj46c%C[=8_PPcC:H@aUJQ@jc,/e5i)MRWBH) 0] jf3\+UfB'Ks#WP"QB0i6g0Upn(Q-a:n)^^o\sh<eGA^24 "`@[8;.F6FtXr\N=5bKpt!>?CLLWB<58:Aa3G$!YP9>FaE6>YRi08]PTC*GQgeXpnS9djJ\/8B6\i^40"ZC=e[O:-^5'F#3B^MlD(j,SCA\OLt0@bK:_6]i^3/QrapY0OcsfO4F-h(n\FqE5JT[?s?qF._HG JiHBZ`;*b#m]=(2%96l#.!rYe4((6K>DN;40gp@=iV_4=@33s=!+%_Q"N.7W)Hb[_/Kfh_gAKBL*NtJ-_!U(ms5KnL`.37@`C"sO-R#rNf25)WKiB`CM'7FJ,!b9#&+:J-6pb52+F[XBQN4WZG1fJS!Z*s,JmA6[KV`g+q6pq4EAc*5!WA80f_Q[>0]2*[tA<G$Aci\tYO%Z?37[Xl-8)9(<'F7r'lO"^*"rf#h1Vi#6=TtDmi0@#5D<ebV8SZE/S9Tc*,b4e"ODGFVLO8G=bO((lg##k$-8A<9-VYbi6Ai"OJ/Ec9qc!(_P2So@aOB=/jOML8m!:;+\/;LDeA&:JRrA'h/0:$)`grlU5^7#[4)Cl1H3'k/Cs-+dDQ<i'(/9(320V0:NpUH;)Uh0>3?=^Am`GiK"R:N7*]<"c4# ;gZsp:3<69dbiHc7CG=Gr1Kgr(rt$,e7;.(oA3C1AfXY`q6pO0%rB!M+a_AD4Pj46.O2mI@7n/Q<[@,n@t5C':,T?AN:^[P57m(nl+Ud4el*[,M2jn5!(?2'M\S*7n(EK$TqA?THdj*g"?.YM3F'\atVAkckL:E;CKEA0_!dMc3n)h\Or^A'YiLPW&I3=NL.Y+B@tATD6MJV]=j[F8N'W*nA'hWpm(^(,*p.[BYnF84Bk??ZfX7(/i3_Aj=fKl/N&#kIi8dIAM8Q5Z%.Q2A"KfX/or\San76C0)s&Dlc!MY_R+-f4A.H;'$H>os4rf+#>f;'9)t7KAqc4nj+cB9)%]UrV6P\pS abT$k>HB YaIYN]j3r[RM;I&#`T-ADV52bqOo->D'X,3R3:=f/$Le%Q#g7qb)2[]^mJ<7+%N%%!`#A'L!tQ-s?Ri??bX:etWR_)R:."<%g2VUQEe(&'H%/4k0eD,Q%g9+ %O9\0Jam:+d5.aE+<Z-D<9F9`_HI<hK$B9r<]&CT,odGn,&_;2sAL\^CniFnAEn*&8FG9'87D" I0OPOhWIHT<GB%N"An(M6OUjJ>):XrnrDCZ)J1MO&=)5G@<iNYD%8@<GlIoM>`bQS[Hn#E)N_Y$j'^N[&!^N.KL!^YXKH6=JRr?)Qk$_c+N(38A=_BrTSJLh;s].,D^-)U]H!*80l@_XA]<'iCPF$#ZGM'2,JWo=MP'&Y?HlMKd;Q7L<1#U(3f%8"iSNFfh.iFXTSAJQFgYp6\B)[TI)]N\ZNti]8+$OKoF=eI"AhS.VcC?E+7I1IoFV+R`]dJqfrF#@?01]/QVYk!n2aiq3,RWOJ.d!VR&h.RRm5"C1-#hSAI1NdXhq'b.MAP#YF"Zs`R+Uq8tV[KQs!bOlAG35odc0aHh=3qirWA<ON^=YW:_T6+CG;qT(<HF>d"?Z6I^.4lb^XHM"'X4E=[YDbS%I9pR[.J"kY6H,)2^Gk-K9SiUN"o/S-;0_sgoNSsh+kp.GAX=J5,E>\l'$. LGU$=Q$Q..^_Y%gf<X<cAI`=IC+,aGb*3U4Mc3k@gh58D<DZdm(+Doc1<UYo.2a7XCP^0=7Y+=F2s>5ft@6)hX;6SSVD(<tbBW8`MVq:;(/-A91'9P4<Q6ss`87+P$@7]V8ff-kaY!*ib'9>2ES,cA,i9;&9p;U`sirQZ[_n_QP/,lBIKpaEs9=#l+*n=cJ&3bto9DC9UN%ZWiW?l>TE26L`D%lcqQ:U_Cf*5d+3%Il0k9>Y7D[r`#pPm[8,.]EiKIIVY:jI*@tNioeS-plYcaZ3YKc^3rUr8kS$a1:Ulll&Kbcs8a)cCXO.n_/?DKneYMB_AlA"giW'AkkjhA$5#Fqo%4khT_2ABAA^QI 0JT>b/E`r!bNVVXXNG!.*]i!PVfh]MT q@rt@:%d3mG8*qq b<17hcTcU+Rk ]d#.Aj0:Sgh)R^:MN6o[R&2i,+GdVdj-0-QIngWG;N`$DBX]l)K0%n;3C)A6$N:Uqp^=2(XBb!]&AS;Y1-;)IAY(o*3,"JEAmOX O/R`(q>=0P(3`rSP?:`mR3N-#En].K6e/h>Qf6[>WT"*pK0=6cMAUgL/hR=e(%Gg"nED KptIn1S_8P(ab9M?RY#^]G\3s(^qcq-6E_K.]hRDiM"sEU\ UWV\4Q7h;[2V9Z+dj!(E+W/Fl//UFb\`QLN%>YdO90@4O96K;_:M/4)W*Kj2e,QZXo!Xq(l@6<'+L=c_?,B3VA2AS?AfU<CkU%`V8&r'fnT  o4;XCg3cRmNp&XF`B/3F&(kD!Q)b.bi qO+=B8G,d1j@Gq&f9NOA60V4'm1_A!?Q4AXINT%di=,ih8D0Ts/i(!'g4/[/c/hN+d.+aUOOKGDD_\lA%-C8e%OO`91bt=gb<`2U'^K,Ujco)rreIN&b`HHJJ*],A$ 9d'VUI5gSTJmoMaidJlfq$3?+/1N> R`X js9,kLt3$GCS%21rQ9seO!e&@;3AVdl)&3s@HCfAj:H8l,UUE^*b!0Q-AL8l\:^#2+ $KLAh&@C[(Sit(tV27A*6r<X=`>lR=>7>6dM5hHA8AXh](F(==jB"mT&mA],Z#nU(50e\=8lQj[Y3d\N/XQFsHs<bNM/_:Yd+-iY2O_$QG=EBqmg,[LGP[d0cAhd_aXZ]0+TY<K]oVr1+@<?FQ8cjK<b3 ZaTEn8A./T>T4&`tY'*H)m!ZR[$T<V99:HA[%h_>?^Vdp,RI;oJVfKp::cpH:\POOh>7Ye^I1aW_BoEl'B@cj'pk]]3EcShAoPXg7jqHI6!KlVl(kb1"]6W?7c>Gg!,;<l2Z=&@QQ2CACig"q!/F`=8_)*e&Lo(4f%7la3F=trN7i95L2$q.@5t !dO@1adiG7"h:7VA7j5m3R+6_k-6hBOgIi0st[<9b4O1q=HOfJk7"TPdB:0NnUf5hg?HUhOO*[9j\=QH6J!fe/f1F/G=O;A*qHa4\%A6B*oFLtVLhNZ,=k'opTa`ao0,]onfJC"`K,CSp6K50ID$C2'A#,)rQi" `bdXVd^7L@5GZf\['!kXp'Zt$9nfEi6$=&C?/7g2$gr58BRQ=*#j8W+J!*,GO`\`Bh<3gP>m4<]'.XQ[DcUA.9/UnWfWBf`-%DTS&g*O#NsfW9P#Ags_HW'$%0RpUZG&kK45VaCW@;7TSA4,[Zt,,-@b18*@BY< ,1.Z_nlhV;:SXo&TpqJGWb99j^lX^,qY>%dSGtf)M'FgMW,*c27@0]ACL4fH4HH4rejDXr_T@0IA+LW K2nA^0ZTG:[B.s5J`0 ih'!10=[:OtA*W>8Qin#'1K,OrS-,1GT!,5,+2EM("!k9RAD=M`+p";q!S76o79;Ii7g"WD^DOT$k4X7E&-mZj&GfkZa sl:G;(05#jSq1Fm"Ym9q 5K!U.G%_@Eh]=,M(c5G[+:l-/)U,)Sl*%A\$3rW$X;AOXhAX'sf*7DBTi>9skJ%GQiYSk');4L"tMK<\(HVF%E&,coajVoUP^V_T5?-!MIkCnGC-m(2`<f  :ZE/XX1XY0A4U^c,f9qs.m`cpdkX!fH*:og;q@KEW(*enVX&$/Cl^' /\EU+NHe!t+I1#"(-h1$!* Nrg/^XG%AWrVIM]]5AW0i$n.r=#OS:E;gk@>mBGWj7(5T?(9AQ )0tYgAo?&:U=Bm"7ia[?PC>0)_qWWUU>/jP(q)+OWn6LTW \gfa>^kXsO^qQlD33@qAUseAl> "FdoEpAY7jtf1mJNj0=!/sSpBU[Ghs\q4j0abhL,A"f,4U:]21a*5!N$p$&9<Q1Z-8$jrGkd6dK+aY`T8V> ]0A;EOf67e\04b.-+3d].\mAkfdhC=@.ZUgng!9dqF$7R;l7)&lE&mjN$/"E,<GiEZd?i61=hFVp<qPGX(j%-5*,3&g=&A@/m=9Ai,RaZB/R>MAsGAQY<4&AF'[s:lG JT&lO=[ck6$$TQl*B@ViB#gPRaNF:oKs?GHXm$91<\D+J#AScG\fPC_!D:5iHm0QoU3aUL? 3WB>`C]7QB]pQE,B#!]CGCK66p%EG6[8AW@"*Dm<8H2#(:Fgtae4#<t,!W'TBsO,"ns&9&'(a0%.jNX@92"p[_l=r6*A>!&CAV*?!A,>/5j<k@nW9CL 2dD!!.#VUC&X&+Q@&+KMm.#oSInWX/I@`g)4Mh[f P+X4sL,#=rG BAaPKtP)`Tao!aE^_Neqd^_@P1[%haI*`)<.sid4>()QJid19Wap'025k,sB(-1NVt\KAlm;/6lnQ'=$EoDl(A!I^6?0JVOO@t5Xj6a]glpg`Kb$pAVC`$Z`%*t4Sr^+3%CT?H'Q8:_C9q$qeDB2G@&NAN?3"2ct2!R`J`_Rdk<[2?#'4I-&eWNbEcH5O^A<,45kbAJTng5cjY3a$@#"7D>DgbL_oY[>2N<37$)A1o52B\fR mdT>'igh2Ij)VtGBU\6;<?g$APIHf EQd)f%VgQ0 &cdkjm\W@4KrXW09na.=?s?6\fF8f#<A5dDVV:peYQf+2i`FH2l+5VNKe+JM2i>d6C"t`L5eqC[KAaP4XPLQKYB?Dhmo?,Ul3(f]AdVF6E,#4?N;@+d[fAH`GcpAl j %m>5q\/=_HrDnj(S=l)gqNXXt5i3tO<G++Yp&["Ds2GdOLaD%Y2sBA*CF599bLj4b))R(*Z8_Q'4A.AQH0RCA3*(;3i"Rb_.QK&$mp56-qQftE;!`5[P"Kgen1K9$;MKLiqCn]Gqf2r5]OUOsM3krBF2=)d5-*1AWrcB.=cQ1W;g+C@RNYI6k6e3Y&rW6XnlOp\OeD:-Kf1:;2HiN`_97?S(,@I6saUZOCbQ,K!5MY!>l$/3P!5&dINtg7XbOR)ngTV^`f1!#/<A86kXZ,?pIg#5>[-;Jp<RTNAm<5KdL)UHC'0)QMpcX631'k($pk^g?nX3\]GMF\g!:C7Hq\="A61_\obIP)fn@S6LR"SiA//eIY%2on`7*ER_3&nS6\[+?a8i7RC 'nACe9sCGZ0\r+A="S<W,!PAd-AABAk'KW@qrm%FtB.R1hibc*@\W=DqaRY?Hp:(PX[*`N8NBGr! 7T\(:Yc(A5\FN+S$(\7'=Z^_^m;L04$/r1D.*%C`&4.Djr<AU<.0FoGF*+<`Jfqlc%4Y?;=$3T*.Lt%F+J;BR%LD1g[\%"F:Ao7A='QA41,ArGXHZ#9 Yr]DnmUGYqH;Z*A5(n0M&o[@"(hC*Y;H AD_J4"lNU*DbhD^*(M11@4bY\)$G]Nt\FYG;>P?kH;W-QAb*iqI'Zcp@Q\P?$%*qX,Lnj4/YT@1Am[Q':WYY[s-Wm;Y`*n ]cmojAboKS"20Coaf1"(Q08XsBeVUMLN`B]so<]%1n_H]9l\j%4)-A;0%4o7H/:W,^`T.YXmMHjQ64\]M#_NG9q<=Kf;(,=f`l%Fi4YL)/D[Q1lCJ1Vq6kpFhBq$4TAVY%<Y^-53WF9hM9bpa.b p*O4odJkj<!lj_E\^gAq"95Rpb>%Jf$@9VtfOQbhA%%AbJ-$@/Tgf#p9ndpjVhjT:L0e`lJABr5<-&Mo/+m9:.)>SZ*%LXfiJLOT2g)HM,+D[U=7hAO:oLej8=eg7#`TK/@FFm8/l M"oXQAgoEK(]IfTt16t]=Cc9t1RKc+1B9ZHU9B+Xi:j^Mdh;3QkL42'MUp$ke?IdFVP@'>-W[PqLNLQ>P<Tm0gJL0NN2dE3]WANDlOI]IK]R?Z0MA7E_`n!UR<d*>[P8Y-,ZtJ.2rlLo:pb1AXoKt^Q<k/o p"m\I2'A[20^#8Zc%]6hj@_AEY^S2:qA`Y`[g1NCYfh.Qd\(b.6.j(/k2;` _3"c_:?H%CE :Z#< .>l]OTo/5DMrp_DDiAi#Aj0];_#:9LB]2%Fd4ni(*BrD=7D*MfeX"aF*0o]Tb<4mN;!J"N#g.Z<CR$@HhB=/HP'T>'8p>8AAqrY0< d*PTA_9JA6<^^cW(E2g_,.O]B8XR<cQ]fAXEb6=-"W^IKSRoL!I5A?ZYh))#FZoa(ir.?JaCrCl;SQ`5alDo:jO<0Xj[o0^=YhC))"GeL-I.c.0>Hc9 g_1A)f(*o^=.TQqIGp1>6[Hhbk"I"rJ'D3Gs2*IA*['9aiT%<#+UB@_Y!IL/`k: GSk7YW[">kK=YP[aj8^X<`&?;*189@+<op[&I@3[)%dH> 5A!';)=k!n@&>K 99BErIqF^-HYH(tsdRoAD,-B>2K]@SkUBhFWd7/7L>ABL-6[Ai_!!X9khq_IRcMM<_$/Y]rBa@t+ab/`maX2JBXqApH<N!\6%Krd=DW]&Tr#r@ItH_3P5d+f[rBa:!S0Y)<]<X)A3WT#Km`-9]%sePdTAeY'[H)@#MkfcG4/j#aV^t;G_$e=Kps8\pSA%s2^1@3\V.qp:U\N<CYZW>G[0>sq@o]A-"EY7f&\VPn)A(%H65WEo.?d>CJBMnB/sEDOU&6_OtY,.)QE?j-`;qF[MQN?[%l<W;,YP0BjF/V4Oj$#VYP.e6kpTB[:hNYeNa8D<VG6@J=o?d2A8rt4^O)LR3mnUWGH:OYCP9)e7;gjLKJKN`2a!M5jS5_!b3/JKcHZm8TJkeLA(OQg+M_&SeI:h5+rM3&cHs[#AZm'C(Hk.73t3!@bhUjUj*b%g6k:d\2K*b5EC^-6FkF $3,<h;-lZMs;d:\2<DD<pX&@+<s1ai L]]LM8N[E>(8M6)6(50.^^!8!GPGer__c-dA:TU]Jd)K\ oC+,0tIjPR9:Y&jMEk+E'p<W%IQJ=2g?/tK'0f.fIsHECsBOttGn1VIjb*LUh^h4J4^KiK0';thTCtSt:L8ke(?cO7AH3^\G,4*Kr)aOR;SE1ECNp2W"E$m(/BQr1(^kmZ<X%hLKID.XQ05DT&&?RN./Q"!HHs^N/ `F=09o'*i]o<J,Xbr3$`n&XC[tt0C3Z*9$SPo:NnSBqb4W[/E6:lKc[lK<pMr> Z?-S?>Mb6eb3(j[+8^-Il=2<#/OH2hT0k>Z0[[ssS% jc&jJDqIj05q 2H)_4:tIeX,9O#k<@3j_kI(\mG`MJRJ&lq6Rlbn(Z(iXCLs3W=D`7O=%qE/a3L@rF,2 LHMlOd/+O85Kf%FH:Z5th-l%DNoKcPk6qHA0 SR`ng%p*^tf^hl;pQaHdRsaNiPIa%H$Fj['!_2IARV6nks2EqA$2Fg)]/dGf?,7HMD)#;=[es(W=gOOrQc%Afp+'Mh<1#3mV71a0a`R(b0BEm%<ITiA8Q:$rl"^ QM_0(\Lf_X6AnUU$*:JH)p-cAf`,-<+k@YnA`6HR8DZi$1o=h<gVr?=26Om?E=KWiN1R-9+clIIYmac58&3)(78U?U4#hKm!l-/OWFWVH>H1H-j-YNWd338:"\d khVYX$npa2m\'p,$/C/,iPi<dfr[b0o%M<2`22AbjVB!SC6dJ.m]"159!!nroqoeTOcQ).snY%++HmPN#:9,Wb`@ds+R5#V<VFS0qrRh>jo\,'$+)$VA>fX(BI=5L$Aq9U3j6gQ#&A1,V]="AX["74tC$$h:@12L8BIYH#2`h>#p)8,PeYJR%Ji?f,8aH!N<j)5NT/k)!^[2mPGL_P9t%+RYM)K6[clBeL:mbt6f]]e\,J+_@s7+@-]3YF JY2hM2UW`!Mh\Hs# 1DU#VgAa'iFIh.&5.7;]3AG^fmD k;A9*?aS20KsbA+GL29'5A ZB=iAkm%i.dN90(ifXAdf,WF*Kechl>6oQ)I%_d[+0aE$a--fXo"o?P-J/5T4&& Q]@ZH<1hindE]&N?!fBjUs Nt6>.(*Il"`3bH2M;,X[_-tGAY-or<3<e[>jPBii^BRB6e\_]%/='Qm?YO=BmQ;\o>6CX<n8r_B7AC@:]k6$ GrWW6iVAMRTPLh`%S-PcHpe:lYHME/F<g-J^!DOFNeZj%b5$To^!)6(5LbImkHQQiK&PIc^biOj,l1(KT`dl!:A*D*V@&g.e9sJGkL%MZb-:+;=TqSllktIft,^X]W7)#4eirn Er?DQ^kBH:*l@LG6O,sI-:s!XZE\B%HfM]r`65f"#U^" &q/VYkjtAL,,=`;>b _jV-p9Gi32@">$<__8(mV-2onU;SI4D1 @+7H%d<Xn&4(>3Na;"0MRd( Ip'GR;Y9-U+%tN;VZVe!C ;DKo"FH69j$OM:8![&VrKWlmb`m )W_hT7m1Ki"lERR )P 7Roe/E5T+Yr6 aF/*4\VFg?),8H'0<19moRd.P:>;:37Eq)PLcE(m+c2_i`L9Et+a[%QA#dhT20^;fq4Pi.b+dYh.fnaQ`K&_s$;7+2DK=G2sBY=Q]D05AOSgkW;gMpJk]/^e_8Y'HTa@hQ_4 F4k[Q.X.gH9,Z]MBh:@O,%m1<&&%q87meWipq8<R?WeZ$;XV!A$\(`Bs?a'Eb-XM_t7h.Xc`;;*r(#4S$n&DX^9::W&m6ZU"&$=cq=?t:U5`VA"noeH2]01.mh2"@;Ahd7f8<rJ;jA.mhBYQ&ARR)0Y/W#(+X CDpTAmf)-\+qTo*X+i8:YP[tC#4%0S5jnpGl20<,1)o3Cg0\honDGkW#th^_a?cJ`1]$A2'dis/rfTk?LeHHnqh!^AZY>,BTSRh1jn2Tg]tJPjU4(J]$PGCb!jCYjt(=e51DQ:%4ce_e#61K!brrMtO0K^)Uc+qA:"bj:P0d-9HL2oj%72HJGJ^@Q)m7A(eMC"AM3CHg-@6plUUiJ-$M]0V!>^E?\M`Apcf&@YKq33(Xm]O`:ARIe@QAfsF!.QnrZ1"11A;ioWci%j3rETcn.?8[-b!^Am39b''D _kt,;D&^\moFpEbaFQk.iL0gsh!7`g=!=<aHm`0!SC=p\k;sX6Qhr)?]4U5j>Z2mIS/Xi%A,sJQnE^o"642#0$%?"&5of9d<..7 $![*BQ#DhFerH@#oL*K2[oPr=8.pr>,Y%l=Aqar\;<V.n(['6@5QItd[Xrn"k=E4jr_)A+N=[#Z`T[FALCVZXqm0C;DqSm),[F1/EV?kQ7U;M?8&]/ALe.3_ABnA22V%g?\p24; TQpW/e$Q;r<[0_6]d)8m,ZWo1sk36>_UVZ]YBDO[IjF*M^YB;>ec<Fl5J6r]dY?38)75?9eA?(^ZVM186JKCpO&gg,oX3C9OrB'?lR40s\97q+kpUMd&(=q3,L&b0)\FQ*A`r85d4AJ@.Ih#*VSXa%2D)/]Q4S-t.gN_!D&CdF)M]U'O!5eVR@(7Qt1jA:5e(QQ*Cp56"jIXl*U"8eA5&47p6[ZE58*c9VN$9+'n_2P<m[n@M"qFII*C !b6UM$G49sAs6&R,8%iR,9(PZl;L_+hXd<[?6T,:'r,P'Gp Z9 0/[D.((-Zbd7^fAAK"'5A=A<=V!dUic$<IGaXIjNJhCC`]O'A10Xpml68Z2L`fUk"Y;A[iTM$W\n$*[Jj((A12]cZ-0W$%gO,5Sbie4L-pmn4b:fn.bI)KhkO]&Lf3$UiPm;'^(LeLW(EAh\m/"LH0*]9#bk rpeJ(,L<q4/H&'LiBY&4B HL]@/dr#+!2@J"$2q?3sG4`,L+0\K.NC-JpU9VIs'.'';r<3skO&Vn;>Z@OO`!t#!jV7C%;bAtf%:gnfgDhkb"B=_pYmF6%WE@_2gV9-+<$cCNL]oAaM&5)m.GrSno/+>Q:^f&POh#KblmSf`3WtZo8.\TS[.6GLB+a6"%m3m38>n@KU\K90Aqn5j+,`"\F9Ya%\@qpK=Sa<<G"cLADD(a@]3Lr6g:EXR5AL4@QVB0a=3*oH6U+haOdOd/rANcqBd,AecrR8s$Hpq(^K(RlcjT,(T`>T!33fYi=[2jmA,/$ r0a.C".=aZK@q$$ Ecg_kl.5^Q'Se;=/UT.age >g3km P9- 2,^RpC[q?9r[:m GcQJ/.M$OO&b.r! /X b.[_\moe/C-kSpon'7eK.g\Apt]612!=B7BS+)h*MY.9Y5Nq'5l\?%6[Np&!o\7!B)6]O#nDP,MJ-/F4PKCL46[EXg->I`nje*+1EJQ4_Z!W?98AD0t">@J1S4" 6DnV-?T*r"MH`!$Ec6VU)2gH##7P !/.Z';K8R1Ns/$0A10KQ9RTd/nel7AndJRfEAf24+#[C/c,WeEn4/Ws ALN+QJ!Q5;ib-Ucl5>O\%0//.fFi\S,c)%,K!,Y_6n0^nD5k\;nmbSLf_l <Yf.cs"o#gAZhK'SBW1-'&q:@-p65<UJneQmSnJ E`Kpe>!GQ_&Uo!mN:kRl\=8_8HQLX1TaOANa/?(8NtU#i<^T!&ABOS9:^:PULc"ghLa6<9ms-QL'E0UWUbYIQ<.hIbP]JA8qgb17+l)shX(Lt8D.8?d+tq$Ym3bGk9Ng(Jq nOlf=C#O9+Q:k^cE=,]+c^T2UY$GmPqRK:1qdH<aT]JNrO'"d/ )b+:<1q0pfm(5OVCT^nZ@IRl!VErQGt\WPB\):iCc/%5so!/-VtIs3\#ab(6lr'h8nQ&.qX],[iCNCa. jU*F,^Z5O&tB.ISo8eAPDW121PX!5k0/:qc-d44p&W2B(0-N1=HPA[AF,8 @.]>&eH\b%N#0d#%P=%5Y@pUa(m3J=^.OU97naP_H^Q6=X5VgnEB\Rc\R]_rPPF +CjPJNLVfJ(^M9:L>C:RaAblU+[7UAfQHWP+q.`rT,PLWD)<8PB LH@<*lanqM=l/.\OkXJEFFV0tA#2'o,Bt7#PZ:bb3q0To=)S%N&rL30f.Id4o,3Ie1Vt= '^'3'^i<t"L6@j(E[['tK""llm2MR?0j[#c>9psXE\M"MS\,?S-Z nG8[C&V5TMabH4XVi9Gb.GMCP"D*ma7(#;nIn(WfG*hp;_2HsUF#GUd#<XMq97(.YXN*1rE*][VJWqlFb-0KSd!09$U09:/D4!Ft%O$Z5SPU;kAXL8qLhn$_3XJW6%%r8_rg"U+jf2!/mriPrh\a:jHC[2+NT&[<m:]Wj.ESA2Eal!GRDOS5N_K*<"lrt :5mk4!]@^thj3&Uq)qKf#tQN$=cY[p`=.cs+3ti+iEAl qgi; Xn7_>=&7XL`[sVMi%j2)/-:->AUAHiQE"GXQfp5Z^@TKQ)YJ3E,)!AFb\IW#ETD$NZ(<;)L4D#Lofa=)(G7QR MNZ'[)?*"K f3teIh<pD;<"p#IVEMj>HA&A+Z;gN(2Db^A,M9Ak7 92o5EOtEhe%H4AC">Bob^kO_ o2)`2'1Y81je?]k_Pn]cY&sg\pb?c]"_ERiNa(5Ih$?aj`>or.b 9ef3`lX+^WpEDP"sAK7E`R?t*R]""hf\a.5ch9@FNE/k`-d$lO4,S"PLKkFo6pmpNX?-!.fN,?rMeIA5;^:m5AKA3h=<m6>XqIRgrkS!XW/W]RtKDUVtY?/Hg% ^A_#tU`%HI7`O;:=fi;CO]t&+=cWkkO= qW<&>Gn4DbX%WG^@LMiOA:DM?F_noP<t,j[ci`IS"?)HYV1_7b=BKZ\Escm41 LQdjItR?ssdT.2)$5i0RD2TVbC:WXR+hi*ACQk_'L:nb.k^<E^#""<C(SJED(p'[lkI@SXIs<=LPV#7' 1SgT=k#:QKgVs-aZ?=Qe+1AUFt\Lj9tdW8qWfBU6WHQsicOFOPVf.JDpnQER\4CA&D"]mt?3E"*'#M0sZN?s$TXXmsA]W0(`Qdnm,r5`73\UY&_qkm7>0[ti4p=eb=jUlQr-%?=tI_*h;j,FGg6n'[1+/YL2e%XQ%5Za?H1 FijKT=bQnh)Y,L5jJ'i(CiWe@k V3I(3\..UG^D,1c$8'^E"d1&OPb3+b;9'"4XIGCYW"3rc@7dn!lHr2NVI#-@GlePX,B^-/%GM_?AWi>=UO42JZtbN[=hB:__5lCt+\W_,4ABdQ,*aU V]ZJ8>7g\=L>KWe>'!C?6+Z)-0jRE&CA-Rps5K(70Sl1roE&LBrla.XhSmI\UtL1mcQ8be+cl4S+-aTsWbdr#fJIVl37Ap$.$"jJ;B'nQGQWIXlTh:(\9L1\kq'h3B9nm5h?D0F6"mHe:8WfR,:FZ`?B:Ls;/A *\FIk_&W!4'B[q=eqCG O74/*A)T;>1s$\fnot$3M/YYiY]U*S2808n3Qfk!F=@lZ=D(\N6ZeFj+6"g!$.Q,J*0,IO@Xc0m+/P )6J-K_8@A,(]XdT]DQ5NdUq)2]a ARkg"jCl.Chf?;X+#Pf4UtXtT_%I$L7&;t.4dr3A^eWFCM(l0]BHnG"r<_ ]3+&RcIbb4/sFEg=Jlo  ZO+@;_]qG09Pf/iN+o*njqQ*]V6NkkH=o).iL/N(eaS[;Fm37b]/hhD9e)Akf;iWg:Y@#=RI`ke$N(M8/Vh[ih9YeB/kE/]6ISo:h>t4PVNP#d/I0jN]q0-]U0)5RK/B8E\ D6.O$J"^tm">HrScj`3pl/G<h+mG%\Ki<IEE/JV4TQ'`mhlkVfaC<QR4N^RSm4gmll`k(!a<TLI^asG2@/jAlO^/YkP k#mSZi7%9]#lrDF""F=qMYIA3jq+mIH-jcd0Pos2U^.kTlHEd#DQ:I0G3=:Ae"C$9-N4UJ&7<+X?QbRl[Fa1@50hoPFmXdG>2JHQ[&VaN/R2qUiXES^'\*L5AIV9;I/Kj>@m[_tl7LZ"K_V*9_:toSt`Jb&HKZ59Jd)M.U=2L*MK#RK]D+k_1O \rN$SjGgbPH6c4q&9<i!ih]RItn$p"i$>40efHh`_6pfr<`;mZ!+'%QF #Z"NL;b2tObIKb,oX_<]5?L:4H@.:^?Yr1N0XKrflHFe08O8iAoC&%_]5 rGLQ:;+];W-d5Xd\m@cMfo]n$$nbFR$D=!*sFI9g=t:UA9pGhX;Z_"G-j[XieTA@N8=8)$VV R#seSQ/-OO1g@ho:05*ZgY?=F$L$8FZ7isK[`M[P"#r9.8ij22-VnZmCmT;Zkg]fT_D= kCt`_MU#4HfD)7#QWf8 nfI<M>KPKFK$lS=$n!\5YB)*/2<)1iAU2"8;OGU*M*j%A `i?USbJHUGmrenT3\=<k-J23`n `r\71d3Z3qp<;*oA2Vh,rd2A5/0%BM18]8j_!QkDN#6oTX?E9E?bcPpA$A*VO!nd3?Apg60\[o"++YAJEYigSs'(p9adY[0>#]A3NM$AnIAo J9E];p^10fG?g./pNe&$.o>&o>1eI/e &n^0m'Jc8eYdG*AX4lLWg9eAJ/d5;Kh-T'O%I\0)\("66bIG"5+2D@,C*tf#)_]ElQom_j%<o`DK^.B)o;YAKRjCPAkAko>%ndqP2i]esMMcetM<`?5+P>K\?9?A=$*OQ#UA]\b[o+diY#>"0g8S]475sOa,-^)"nRcF+)ALo_FpEA,+/j/5!/4pR l<^g,NCj)eD]OW,-T93p+T<*e++H.#Y=/<GSn%r:Aqgh`.0#8 BOHC8U+\%(:AK%-L1aK?bT-dr7I2]j^Af*tf;=-Yr`qNJ,I'Or\&]G4$A5cs(MR^mL.dtc:69/(grAXFK5QC#_I+#pZQJ[W]VjE5tI9P?&tbRD*90"4UQ_9"Lb@-dTB&0VH"F\8i hB00'plbGFAeEn43<iE'+b-9C,,%#87tB*4.8@aA=Pt!66AEXo`/9n/M_\q4$\25!@_]0b?;VhNCVI$d,fZB jG'N:]+P7&*l3d16IQRhlDaimVYgCER^8"UpmE!9#X:;NJB^Y %16FGrJC8Hd[)EA2?[InP)Y/B/d>HAmhBtKs!7jc`pf6kV1aEA( 5B]9KBeVop.NV(:%GT.b.Fe`RcrX$-]aYZn$m@4t`7n[GVNm=i`0sP_$[;,2q=_4QW @bTWV`dCb8<^hcrBaqNB59ERMDEP[ps"4lRM0R<50k>osK$U0s's3A_n`1]6igsA1W1PiqsF3X'ccZ/9AO,YBP%m]q7N&+Vbcbr8_b7X8&n<3mbD/."]38%>p=Y!s1PhSV5ld+qO2oK/t"D<d"fSaGINFrNBLZ+(hpEA7[:J>2mgS)r="TmFF0^5 49)qG-GBn/k X`[J,nI/.>Wf,Cm'mI7B9\PX=.J<scG*mj/ 'jAY$$E rJ_ DTqPA80t"Tl_b6e[M:%-b)=AT7k`!+;t\+2?k4fge$6R+NXa-ElZr4L1K%%Co-\L)-ZIM2hr+<]qaE(68L[)KRlcf.Zd&elS6l `rPBO= $2Jm]>]00CBkj)I<X<dEaVT66!,Y0P+3qG"9<0>oSG%isn6.K`cS4.rX-c#`.IPfP:I2Zo3'F5Ybo7Q4.24%+:1Z#CiiK(Mf9,>VBh'qphp%]56afof\X;UXnqL5&qT*f?%g2RT5AL R $j!.baUTI57,H7"[m:A0g;KjN,g9X%4bZl,f=nQ6.r;$'2=('\pb5&1hAfB"A1!F2!Ig>M5`Si;dk' Larm2<:[GRk%D6WCL_%K*to=+]RhCCqb(\EZE#.XU\geYpA]Q-S\Z24Pf(.FI9NopAptQ_94Fm#:kFBj;DW'K$a3tAnF3#oY<%EEiskpRq-"q_sPeHPIZ]O7E5E40TMV q3kU MNVRlRYRWI?tLlsb!A&-ZQ2Q0:j'AnA^NC*_N#Knf%+RO6EWS5b&s+hp9n7Jjt`NBHoTa5>*$C=q5=Zt[*jhRQRYX^#NaPfE;WB>NYk'PELnsn5.a N(8QWAa@VpQYUMO."U_U'j7XFVr]T ?Pk[HDbi6$Y8)8Jm8ahPI^3]$lLe<D&NgI!1G.pc,)kDg$2j 7GT:`R?IH$iW!Aaf$m=.@[CCZRhk$aMoISYKIjm]T"(VFbr"pre5>Rte_fA7VA.._H-GcAtMsC%$k&Er5QY>] $eLqENb)rRA&]"L^!0p dUK!l1NUh9N\@1rS1MiGSN4r&B\Y59U38)E+C:[(=bi)ieLR?jTRY;6,f%A#^(qC%j&2:[bDN<mEW&l5Qg'W YR2AX cRi/iA;oMJ!%^Bm%\hBaqE>:o*thZI,HHk7`?o'WbA=$TfE<g?EX"(.Il&HEg+E+3G+/L*>nGj3&^@<MrOK8LZsF/ie %+87>agOQJcpQ-[)W?IgsX<csriB-(A>O4Yl0h;fnKaDU5oI&FdiOeC$S2=p\SPR2C.pdn M[.65Y:b",dsJQ;acF=pP P)Q=OZ3N3@kMp\GdI4a7DUF-\r=^^jJcK.V26Ul#2>=A260Y8P&,g&aYR^fIh(rV5dRt;IcInk8E\Va:++%D<+1ETI>_:#"mjF/k(SYr0 +-@.+mWLM\=p)%XBFN/#Ao5MX7>$BFYkq`<7O9[;nXPLO)Fm$h!)[O6V(/hraN_=1m4o1q6benTM+U-FWJSEtI$&UKQ69cA;Cf5qOaE\A$B$0W'ns/F1<imRFbT"E \NN@_Tq_M?%BAHa%[RQG`X^UkVKsDa$@o<9pb&e$=T.-].[r"Y2K9J&cCpb_`a9THa\YZY0**\CESsX3CK(8Dq l!rnO [rANI#bd\0N#f-S+(R:]&p$7thil[tC!cDJ :*ZJ"a(!A7fAe-rFJo/Ap!G+BN@*&m$KplAA'7qF1bsreDKeahX#nQLs.mANJAMif4OQ>lJ3]sl"q`T#b)o6@CGfs3N+i#R@*dsA;bicGN3I`ABl0pN1[UA0HKOa(RKdS,>o`R>?r-D'hWG]iTIAA&GJ_T)!`0I$Qe9MH[]3Ar33D4nd5(g><^5 H8-U_0 5c')PJdA73oOW?I],hh3C1.m3Z?:AcWU=p&7P!<^>Es_NeEiN-!$S1=r6/4WA@`LamN!o7>Am%Z@"\fn*O8IqFGp3fr6SGN*6BC/`R?> bt\R3+3K`2"C&AbU?>pk4]+MjSTrHs(F-Y.S4[9[ZL\@$IIB[W, 5.AWBXqJ9`,9 /k2)G PXeir$/jEdp<n2G<iitj^R^[W'Pon/.,qnj0&MqBL&N!V0dGO0.(dR3/_iW]BK'4^C:lhUG]7(F;:.,=_JtD;s.`4Q=VBrBCNe-ID#03cmmK"E-0P3Mf 7A-t>^rdN&A JfUa(;<6\4/`_^OkN91CJ*dc<ZRSc\T%,!*ftAMQmb=AZckKA4P?k+&&ZQjM/K8PNsEI'#K5<PrIS$a1sSr*qBl)e'@3UsAf(7M)5YSXVBQG.n-U#8hM#(gO+ciSfo@,^ITW*&[H0D(UAkED2$cg03V&,s8Wnte:tQjR*S]Q2KO&YA-^qXS) WH[D\KUA?)] :T ^+cp'<kS1RDo;cILl K8XeKSCSCA.2e4cH-*j^(B;9$7K3%\s:(#AHR+Y&M@R.qU6a$K@8totIK,SOVgK0Sf<">#bjc^31p*Idd@hkSj3)Ft^P"oI*Rf%OlZI8n):UC`R9M%Yd$>"]25-_,o9"[bNAm7!@4HeP/9@O>rR]HGHhJmqr$Wnh@:Uc6\9.bB7/-QN,3le@Zk.T"#O#;g8[lU&3J>U^G;emN)b7gHi*^i,h(^I6riL0q>V6%ON$[5 VU#k#O&KGXUBAoi":>TKBbOld8Cp7Z*QedV!)qEp;GeRmL#0L1t)Bg*SEp9ZFWDZ!pof[[tfifAtE'[_M2ODcYe8G-QP\%`JimAQM'2=bQhXtt.=]a\17:QZ]>^[KgnAgU=HPk0\Jl2\<fr@H83=6]+;d)J#PN%*`<d#+?E]&Dh;`'Nj<7Qp#b.;8(#19a>L7=c`E.=*?kij%`@&C6fFG73qHg$%KAP6r4CFOi;7G^Y`3i[2Y>Ub&rLr7mp1>Y,F"]_0G!b*/(rC$Lk5F%`'BHD%AU-s%oSq[Ti-#[&^0Hr^j4b^+d@1)J'on<Wr:M:>Fnf"KL5;Ar=E<fd0-<Ii_<%OFfnPYGS$r-`5C\A8r&RA/J[[MtlI ?ir4sO?Gp,U7q\=pcY1h:3=Ajb=kWP19A!P$WX=(+d=h\Z8 ZjWmqq(4R9[=]Q0 #cJ'?Z5&ch4BDlL[=TdUV<JpX<_);ak/+ras;/ 5m4UVp,_l=H8YpZ"F+rAt6q9(h%1J)hXF@"Q[)EDHfZ0YDP,1H2%8?K&ej+.VG33./rEHXA^2PAd;M!/aI.]e;)k6qT?A'>o>,"#>TGm_(Z\/<lW"5Z`CErlS*G0RFP<&^8*7XAqBM'@?4+8;W-B)'rjD*_@tm)'tfoXspP7 X!"6n.]WGW5W(\>M>JXZn!-i,;&[Tg\`TqnFRTTAR[7%@_C^kA_nfNXs's!f*G;-ZW=,/%mfR?p70-Q-iA`"Z4:qM0SX?tB?ao1,O%ZS4aTe4[_(P6*g&7,DPj%DKp]oDtlZn9sgcK&jaFE`TjQ[B]05&\E^n4@e*hA]ZnnhoEA.sX\MJ%aNJ]NQB3WH]`[6d!$[m X ?XZmc41Hj3A`gd\,XKf#X)oCp7pgFt*OtSUEe>SdPD`.X;b)JaNA\^n$Hqq^Mh3_r?+eHn,8$5)cDH)M-!<T3CpqYk@e_i^hR/>eWgOZ(]mlh`AJ^,tDp/$$J&;pH\%^\Y[API<t5D-L[%%W48q<ksCt/.-+l!0iA1s0[ZD%el;G=#iO^tNiH=)s^7mW;FS$pN81DN4QA)hA_/;AV3PFbYYg<Qc6e;T@Q\g%p;;)$.\dEbNA!]B9dmXlpNro%>^i+AHK/i,3?26(PW55Hd0RC0VVPF?@Af?AViM.k brkN5LA3M?g_dD+(b8.tq,2S"F* Xtj.VbXlpKtTmP,mHh`)HLeXP#tpcBeZg-K)tlqbaXl'!E9%Ejo9P?0<=T;,ANC"5Bn#^H]?-d9!Se'+mp&o6YR(m25k2Rf@`CFUD[kdAQtj'I%NmQ/`W,BFdMG;;P%XaZN@D_.TTS5KfG3W]br<.]YjY'k.V+O#[0l1O &#g6C5AM(#_I.*\F.No3^C#s6<qr(Se/;aV,r-FA$40"NL&dhKg./L_#Zb %ipAa:Pr<Nd1j<mme*7J5;35_E+!N.*5A1f=i&!@;2iin<c-@ce%I@$U^?U hG60[Q>][S8\MYs[iG2I2dPPG]W5JAVkl<U2[7?6E<%6YFlr45q"3^:eFbi.;:t($pc6&Kd-:U2\1)WK;dlp4AARd7!]>Qg_EG25j7`I'(jKo'IQ?0D]L#X,pf6=<j^d^F=p1en#"L'rCspF`d1oRQ'4jj7ZSi1Wek9E1X+?j/+c;gCB].IQ*sbj],2RMF`pdJ2e1Xfqs*^FYfZ[BR65^sIci'][RNaEMQXW0pL^)(1g;b:YBW,^$.SUke>-RSB9j),A@6.+@#EM(_esBY)5>PX^L]&F"fgaFS]2TBfVJ*BEc9@>K%D#:>Hk9R#n8Hj;n8F]:;Et8UD)ArC:15Q0+1snt3Dj&\P.<q6r-@S%abjA)K6qe*+\#tIlsb=DQjS=.[[OD;&k;T70#&X$'A,>W/bPTOr&dUS..Z1GQK*KA(X%%$k/md0ZmN+E21iLMiJK'GFdS'@5L5!$j!JD#hJ>9s#UsqU':$(#)!NoWq*k$=hsXj=n`,AA6AAP"]Ak*5_P>0.VRZcP.A?0]$^P.94Xps^Me753/ONH_i*`*7oG)l!g8CGG%=1-fH^BIU_t\#?Fs);Gf('Xbae<<=:l)j#h\e;rY.ZU#F!N-:o.1-<$Qk. /M!rbGAc&r%=Vj&_,i-+M-"G]fX@1Aj#j7J+$/5hfbHUOA>bmb(7]@+jYCNCg>B>9M;0#rCq5oZ]r9@hb$e$R:P"+2D,'J '"ps:gb'TGEc@'t;"4DJ^k6aM-)(E*pScW4dAq%?Yr<T?:2te8*@1Edk1Ef!A'b;^.*O9q82Ps_>^,[!`.FW3q?^6aF40AYUWn,GM$Q3ZN.a2Oi).1P$>s008oRAV$XmF(!X:HeF:EJ`E$tnj,RSAR(`(Z_2"=A,)WE(j65.=r-3t&6b4[>/EQ5Iii1OBA:o;''k6q3W$N"+DnJgN<TAod3_g_IB&sd0-E<-%f/0jL<VPh8]`5Fkln!clZ97BarE(*hA&7DL(DK+1Hj/f\pS.>KN^2%:[Zk="Xpn[f@7#GLKdFi<[>ZO"Y@ 7R#Vn5DNP]kl.6?QX<]JJ>"U(G>6;TV,'>X`N/>^<6e]Y=rEG/maO*SWSH5cMYhpfT:%TC3TAgm[aO&f2R"WSX39mtB)ED:`;-;W*7?*Oa6_I0YY[HPeFAsQ'A"5s_f'H^%BUN]1f\] ?p9LX+lWWreE"PZ].Ef7Qe2P?s6-^$t&'T&[0,EaBKthk\9*AlDW$s)CS[Qlib6-r[q@UshcoJBUc7ndrtbQPM2K#CBm6SI,i&A5:]>C +4_ZC#R%:mKOq0$FmMCUeP!Hg^Jr8P:% ?e%Jq19AG.\OAbFGV*\B9Y.?j98=S=bJQVrOjV&hHGTf+kj6@%%l$El[B-U85[bg""pjC6;r4Ya[dN`#[N/$1\YfI*l:DiL%?#N`9AHh6A2rLr(Vhc$[Z*C^U?SM1I86hto\\Tb6@UsglAIo%L\"lbh>h]G8/s+4)a *4olRYgfXB,!]:BDb=DA)ICp#)6c!BZ\])'K>PAX$,'0]5^E-Z<Oj*(F_SpY4'9e 7$!Y4,)cLF4QN4dX:SBtPG ELLYK^5AtJ$B:Of8"pFg:r?D*5);**#/r="Eg-GlT!+oAINJVC;gXPm(dhblN;EAYE]>I4MEh(!YME9"dkX &Ar]K?`R[o!*knNfEs7,(MsWD-?Wibj_kj`#$KY]X/,AohF1U`tdg#-3F"J4QOrsep<3#g+*'3.T\2,3l$>I>MGac F)J<rZ&n%^'C#n/^;EoWS^'j7?cGhVS4-mY@jZN'UR14NsN\_#"i m]g*5_s!9k_a/HF[0G0*_h#.af3s?q3]U<h31YDM(0Nr>p9mi=rhr"%n[W*BMPIHkU"_:]Y?P*\N]AfdGkR?HEoOn&Ge9)BkUjH ENcm,MV:EP?QB>0B!SCDoBWb%I[A"8A7Ii5A2A)>e;ViJ#bC1XQ.g9jqLAO$nQe'g@ISjnFkg\t\Q^EVg:e(XaU-AT2,Xe.%D-<Ta&s0NQ`?A(s=JK8P)-P3A.Yhf?Zh:kd$88sC0N.C*a`d&j9512Z)@+3NhHg4jMD\?!d&J9!,]Fhl'tm#e4_FA*IJphtmgdZ00*cBAkkAW"t0"S],DoGBf@?l]O$%SF!m57pb1\EOOh%L5-W$LT`4lsb7MP^2"d=&;tW5Af\ ShQ<D"3RLP3b- YWWP5K_HCI\ZL\]1%CM^>g`<fi]qA2qPtJ2:"-Kj;Q,`A;LUqAm<cqA-=X4edXjr^/.D)\`[!U0Gra!^=PbU5<hD3nKi"i#%l& o@XN9k2sg/hXsL2j2G!!DnK_Ik -O_E9d?mAM>W$PFDP7c_C1ln8Ui]pp@U*/2)'lc3Q>J$_5Nl%.a.=1<<46LR:WBdA2ETem5-^'p[6G_n;\gN=)N@E0DP>kfn!_46eMq`2Di4(K;+1G,X*!KZ'&(Gs6IdK_c<4n)p'gP.K!hp%g2+'pAHPdX.kq4.H10aO($ns)&JtK:2?^X=L$T!nd`:oHb$,O/$PM1 hGkFY5mi"^ZHKFN<0*\0rkWB[()Fg.1'^8pd#G`sA!X'r,o0[eiF^CM%G0pmYKKHg%gIWJ I1']6cLlFKg5nW:&:ofb+Ejk&naPs3iQBTG7H`.UDg<P^Oji>;n'<38XtqH6-NX!5<c,K@W#GU$3FB3Q+:&taRkl2'?W/Vp,I?*+ SLp(a6f(*?90(eT0<drjk_':;\*i3WI.2T]%SW&Nn!t%?a? ;^@0af/pB^(c6S+8.N[4:U4e^nq/38NgK)76QK:cor?:lh G0YGJ.gZ9FS/()) -4 2Dhaln(^p,H!T7%&iAa]Gk`:i'UO_e/Z=JR6l[WV"I];WTHU[^l74)cOk1@(Ho!2UM3SW-[-]J@>rG*h`n>r@'`.c9&F"eG+A?3G![`;O%*LiB;koOJt3a,\aG9L??iGc?RF,Y9)FH 19=WQT0W_bU -:J/!3Q(R5f! gD9&5HK,$B=<S<JQ0!qV^-%Q.Jk9CYPsml;>d)1i-#,bT9Me9+PEY4*#Lo#bK6(ADp+_8MLO0!R/esc`#W/,ksGpTGJd1k0Zl8dk"LrEPI;`VfF"&]`bl<$9A`NPBAqEV91:IH4-mH-b$?W7oHKX.07\hlj]G`&QBi 4R@+l16$ T&P7KhnF_LKNG;DtSR&ch&;j$&828OT==(BMt,/WGBil%iW*j,HZ=HRO.TSV7m`>kbWTo9P$;l#2;spkK\j>E3?h-ZpNH!:&50TC]\&0-%hiHeZf4j<39n1e_Bl^+JhkBJA? DAatMI%1rZ(YF C_c!2D+_`t+kAFF=9@S)fjBPD8L]Oj6%J<Ul<`mbNC_bk%?4SE89r#t2J-q"6! mK2c='Gt?%*!VcRp90]RW"q`;B2nXCMf:.^(_=aM&VAIZLo@mm(`oC034mbr6/r; /.T#k%+7!H"/+N92`nfL9sUH(q_bYJlpS,6*1A>s-X!L9 =(m'o;L.:DWGC4TsQrCiL,t_RpDC:#]"lAeIjm:fFc?@=, PdaqWbpis'*NoC_KRFlgiUe=&K+4Zf7V-)MqASmc)6hcfja5WlS4oN=*Zbr?d>"5A S`4(OidbFqk",r-O N^g9j$C7Io9^!]KZk"s:m#90bM]D5E)js"Qa9+lk'Xb+ONY=,(-1 4aA6OgC(qdOV^"N] $AhU-9&2Kd;^UM9K`7$6.W3F1Fc\sp]/%]rG-Fk-(jj1qNr,5 5QqnA]@A[Nt/&0U1?eA?A[r6&Bk3,DjS17B@g4o[6Z3lAT>PXK"MG1fl`U27L<C92i`6A@^\%Ri=F>-7IRk-//*\ k+6OJC1M;X<nX(IgkYR^(%3rJA@E7]8K%7.DbQ'P]P*ef/f&L4M!]9F/TA#]D#+h3J<D\2AIA*X?.!Y7A7Xk#B:%4.'[(AS,a FpW>:XY?s9-VjH*AOQ%QGK#o]bm$,`hQN&$0QF_.-(2`$"cbE0jQrH7pWZ99Z#%]*s&i/ctQ?r\9K%gjYMg!ZB48"q/q+n.fW6'*`0D3]gGFQj-B2X`&e&*Md%lgf-2:>lk1AH7h5>6pL3p"PSO)^)!=/?7(S:5%fpb<.]"!frm;o5/.qtpr4G,=Et+<?\Kr/3h@_m>A"-_VS:Q2Ph&A#?p*FVUi9OPj)sYJK/d#Pj6ZU =gXMCK?h$WTY:#JjN=AA]K.dZY,B;AGO56C(c'g]$P-(\/DF*X"/jl96JA+gJn>l;]RdWp6jH#pNdt'1U7^4qgNl7K#O;PA&\;1a/s*,PmG$BZj6L,5+dO^Hq($;\je4;`5`D<"Y0-[o1_6\r.AF.emOM71,=T])=4RlPMa5g6.)mheX*t6)M7cVKQ8LV!BEd$R<. h2GqHFC0Ns+s?JYeXAt"C=H(apc;]J0pAnML& $Ma55qhEp&k=:9n7mPTOA7P8rS_E%an7;M^(:aY,D`U?3YH*^Zh)^na=bkW@JOo&f?E\qNC+Z(ck7%Z/<asX>r8F]c]M/si't?:2I@;o2?FT8O1,iGhM9Lc/^EB5lUKa-Ilj_f'b?KH6U)A&A:YnG.k8;.gc#iYhU/5PKO*2CkC)A=Wm9hAF[I?7rA=J;Mjb'9n-nQ7c?_Q/$L[VOe^_q;%%t)@\A;G&r3E1-Ce6hG(sYt9<qAtqC/q(#h82JgF[K"s)R\>)qtJhs!gjpPa5H=Y^sj`7M:3l')69]7h/>Oo !E]7oAFhAf]O h<=)V+74ipr4'OWir3bB(rp](X@B9(j>O)&UV29,=r`\E\pgD6aLVO@4]p=QrA^d"48KtpS=JAXLU'U)FVN4mQ2helEl]%kf L/aPr4R57HoT+(JOA?Of>:BQ_fEV==N#Y=D-!jeEcm"U,a7HE!AI#Ap=c=p!?jq8rl("H/m*:3iN*+YI"cm?&!;ESGIao< +`8Uj!FAiL+r+lD(oh(\G\U<-mb>Zso$QRskn#&=QLl+)M\&D,mmcP(G.V@Q&\l6]%WSNUaJ1\EV+-Mo,H)f0c<Z$>@?=/-?hU\8n T8 9o4M.!^]X%i5VV7kL[l$UT4?D!aJH!:Lp`MgXJE_2LYVSA0s%P-a0[p596d%s %V!@0t5O#e(+ `E@" X[B  >tQ>ai%n/D=:Oi&@%,Va'npZ so4N$!)k,_h4mpg ClW+6jrf^rt@\7:L0AUVG6j30g+Dmda`I*AcG[r-J^]S5ER:L ([\ 'Oj^$!PT^/K%qWl&^VLV@'Zq`WcbF+tL`M E#RJfj27.I$rC_hh.W==$s>Wo^8U<`3p'\)>6#:Kmt[IS;/FA1c3MOO;15qR\k%b74fT`^j8NQ]kbs%N<I[E)@jiM\6`4]ni6eppR6KQ`c;cl(jM2U-0a3rMH`/qemm[UW%</)WM>.5k2))<Un)f<Je5:;NZc4M^GA;L6YF(a&Y)p[:+*lA/Hh.H1V3R:0.2JiY[`0_LaW^qNYR:.^lJ07ImZKDCZ%AhjEJ9-gH^Rpl YHX8nCPVO.(P^5.'h GS@\W%\I3"JE]FtA,ZFGo-t)`5$m$80ZY]M\#>oGJ]GVe\gY">Cj+cc^:RgbqaGOG7*aPjU=4I1h8%Ym&)O/^UdMO]s_i4aCp&:Z8C2`R2BDAj['ZE(bY 423me^/KaMH04tC(Q>3 V fiIpUX>EKdp_.bCc2AWW\Tk>?KA-Z&jX$iQ/*iZO#HFd1:SrVX#E[ZkG.3hbt@*r44i4&XC/K]9%?Hs3caUV+&fIqI21*h4nnW4tVD&tVK44p];U,Y;LsLM8&>4<jt1FslI$k)OY@ASS-q;l-sckF)4oR<)5Gi64:"F@j4&?L&JE9:JX RL`>l3r.:'YiW>)q2=K^!3h9O29F_m40jW7Bi##fM1^DnJ5oWrN_O:d;&SX=e=Erqo;JHn\o9CD00qVpT4IjMA`<EhoX&(F4Vs0=cZ^: c:jadc6q%'Yb]](p[7*kk&-;3mjtXf?"H@AN6R*N,f+WpTe9g9 n"%[Ki`"k,I/%;cp9 CIq#fsO/A g9#p(AE6_cTlZ8Kb0M9fesQE1#FpN[L=%ef0UHakB3V^Ifr6dta%pGZ0hqK%WpD)B!1IPsAgc&;.8%Hd1JS[Ra(&;A^ls=d7s?:#3ttAqThEs^k=hMSj-qEAR+a,\hUD./-=XH1Yr`!Nam)rih#.=)5j^_Plm%.Er3F#:;n(,f()%62NEf0,IGbmK9hfc2X1M8Y^`"QW4t'&JQGpp?k&,.\&%S_3XaetpOT'>r1')8JY,(p8d5FAb1ERtAsArdH+)1!>c/As.1Af4q,Ads//k1^V%4q1htP*"KAAU$:8Tl#Xp' SY7!a0h)GrV2.g'JmbYRLO)LRA<4b>"`LY([l!QIeWG; gd,hdog "Y`#g+M:b_O0"\.f9E"1'O*o'eML4nD@:ARo5/G>7[rpTP\i:7 tU!rb#sBA4EEN)o)Ni[ ;2/-_A>F%U)GMj c[_s18UoP6k-A-t@"aN/KX9cA'Bp'hAc3Zp'i.O(iH=o4b5JRt6&`C\RE8D<.*KA_2fRf-IR?<aDo#7oeI+ @cbq@6QnaPeG+q@RXQSS,A2]J:ce.[VMq-8H$dJ2?Y<p<t.g]Pd]06^W.C94"7m?6F]<r&b&4$,FTt;FLt?skeb(&`WCM+Bf@04l.ECA_^je2A/Rr)%X.SVaSj0W;AaJK2^?m`Wo3N;[ eW[TSiFn*e%=h:6KULm*>PGfr,$a6gXYkkZKCoEYMCe*HFbQCgYn$GfFr6ELPGH=QF<Wi%7-T8f[._L>7g%p;aj)dPeUmISchF\"]6P'FAH0f7iDjao-n'[qXI"PT4la?DUfc9k?'m.-N\i_:dC6/'UfH8BSZ!rAAd/+58iD,\I;#"kZ-NoUr$*li&@'0d W'RnmA%&+R^lS]WQABo2P3P^#>;>N;G2K-fTeXB%;%8fn;A,Q%%ns?><8o *QJF]rt7:1#[loX+;0\@"RL&[*9+.d^2Oa+2cc<d?\&kY;#g&CC`ik)@6F&mP/(#7>$(O>kMPCp3&$1aAV&(-aL^I$QM6?5UnJ"@]_Vs dBbJl_681=,g7pNAcVD@6MFFR+p=Na^QKhb5" m)1P&9d](6!0QB;@ZNN"[^RIGq?dteA/H<n"\?Y?Rnm7@kqdK/GqnUlq63"3rEJB>&Wg?!NmJj)n9j?;Xrn<t,8N<<IRL5c*c=_AV-Ddd/"L9Wt[:k]q+D6A+tD=Tcb%Yo>)A.G000"[<X2lh.ADb8ZAJp*JG:XqD0q s^T3)jbPK3aX[)r+Dd`Kg;3YfeVEotW^Q3f:]o1 b[h3#t\T0%V8Z'q#lo ^'Btf6b:(A'j_*J][YQkL]tE<U6^<B(tIX":-[>?bIi982-n6rAf`gnb]Li9_pD_00p\O!VJD#RJ:SM7,.OBk$a+/%ehlgR/`-a,3Dl[6U437I(g-dFm?3a,"0WAS`MSdckj;^91A,DS_jlfSnr'NBPn9An^:<>2,tT%e2IF?MH:%T:om3@b-H's/A8hT+",Ho@<0.:MHts;XK](7P9ro#NaFHsR6n#Sgd#56*RM+t95gWAo6;/RK5Z\\kSam[(9@)/;_!H]eXco]q3+hUF Op8eZt4 `OKe+LDOF]qTMDnY9!M@Fo_i2LFLsTlnM@cqcl(t*a/Sd$Vl@8Jj;a*@diN/...8;bboWLH ";eF<?%>tsQ3!S/U;]UA_n@+n2://?H"OZg!t/8BY18p7HCLq,]h/O$M^XNV[]B$!2mKZ&Dp#0dPk1lc\9`"OC!j^ KqIoc#/s\GAfsW18)-XA8fkOT7W;_BJGar%p`pQGl->3%W;3kb`NBh;jlPKtiT?opK"Z)m#(?2jYIt;c_Gi=m)noCh3nM,MURUo'"-A@Q$E!/YanjTG)F'>lV I!6D:6iX]8;[">h:$aQZt[I8J5b5ha'':)oK';Ah",Zk)mj)$IJ]53kP\9%bPcf2q1>J q;4c/b7U 3]5<Ji*PH&"e!2&i%s,PV&:+mM&gT^osaiZ BA6 jIsjqOJs[*'2pJWZ2?!MPBB[No_QWpD*8=41&0ikriorRAi3[<g(o5WNi-'-J>QaID5ki5@SIKL-P7`a h9FWc./jQndQ3gC&mb&>EHe(m;rHk*JW</1(VW&be!-A$] D@rmnq2ViiH:.C:#7WS@?a (r\C?a:A39Ms<sRc'+[1DNX3,!)q>SC `[`6o'U#MGFW+=#%]>gYQda..\Uai?714@2"n`26b5N]AKfOa"@himgc:Cf-?$K3*Na%'2P$R)OmJ48%&[i6c?+#f4@t?<W!IF0Rq^[V&JqSmAMFB9+7\r=F2MSP^l7]/!RYS.INp?4,sPX!Mt<M[B8.A_)Fo8!kW\f8QEh#&3B3iBXH?X'J P%2i(tAr$AVa5@f:4BT!OGqV=..\jL) 3dEfc%lYY%0_ ,NNhQd=l8SUT.clsJnDsMcT5@i`CZAT?atToZ?([ST+/Yj^t)4Pi.o>A!jBGktEl?gF^"=rbPBle;s0WfFpiWKpOO;#<Wfg&UN%]\Wo*aG$D->/5`\Qnghr'\0&QMbrZYB2nrrB"E?n9@F;/:;!H:/a5`YB4"L%+ Vs)6n^F'R\fA(C^n3f:AM"`+!#Pr*!k='5ZS'<lt8a0qpkHDcUiL')5+0S6>Ka-B!S]7\]W5DnaQZLXfeT0+l:PR6l[ZhB<6p2m#$XUl4K=-00dVAat_b371"\eYVPe+kK'?gFA9T;PAG5SFqN%;Jl.&FP&G?KG?`X,hdZQr"3)D#.ZrP&"eFHP4\>,>A9e_M@,51:Oc6,Z*`m?k]Ej@9B/l1e[/NSA#/PDK`+R^Z0:[$_9=1R,$!PhSOY_#c0\<<n:TWg!J;JJ>;"J$tt:>s.0Vn\L.V07Han]b4!Ti"d,M%5)AC(8JohVLR5qJkkhB 1 4h:t()$A0d4>=k`nS$<^*T`,?-#4Lb/A/HC7<l)I)%)T,!lCZ6JF.sX$>Jfnt$Ys;@p6%%ofb1eg1d*[Ob%,S?DP#"[2Vt3,D[A'')R>XQief!P!GT>PaSE4cD&5d2D B=1b-*9`kAinr6pYq7QA']!%JA\b;QE&-B%76m*3T 1d[lW@nf(o(264V s];P]5A=;Ad#a2BsM1>oF^A+<U%UtGDV%G20PqPATl36MkMK'50G%:d\> 0fTQg]\ofTp`<&_e[A>YYFAo7b%#?\QUVS]l^AQ7@a2>WDBm&T)[CkA)H>h7q(m4)-Ilf6Ah%*rZ&Od!"no"AFLQFg\]ODV+j+_/Y#%c7fLZHD*USnfmKn=W+J%Y><F(Td3NK_(/F=b%;?)Q.mW<c0a_FgK;Qj'Ihd&]RX*?7o(o]5aWM//0r2*ciA`lRBLh2N8!W$#Ha0[T[[U Tpo4oe>\$H]]a&eIRgLgm36@KthJp)6^6r:AcJjicCR+dJZ)8AmNFH^MkSoG9G72Wq"oRn8bM+4Sj0Drg&)b<9s>+SJ:H!+B:.R$rCl%@r*8VGd7lmX[/Bp(\nhtU9No7OG%Z.n%!t40&=RA);(h&2re#QVjaI">Ie+&DpW"%44A@l$_?P*S.q#Kp;-?\1<n0S,C+^h;RfAG;@KdcrCfFcYOl3+DW!+89kD$>`((G9c\?G(O%^A6I1(%j"6_;(h-oS05i*]PVsl!B1bGr+,#F9B"Trdq2\#rXiV>&q8BTf8)ZPl`P[0dd&chG=?GiW-LC80L`6GP8/sf:S\/7CJ_,`sU!VeToliSQ4)oN,E2CjEt96D'A'$Jf_GHlPW05caah,O.?AjL3EcW0 U7,qU-E!pKce(2/0`8"77bgBQ*"q2Gh.+[@.E"tn=X0[h%CU1g?Bk&,>2d7nS5qtU!%?b:3<7O[!Ym;Ws&F.bq$$8V/-@D38X*<\46*T VX7rg$cCG?#W9 =CEi(:AYk38OAHBbo@6gPSM\)FF29a!l6U9A9iFq..l=45o23O-Y"ql1KW?!;O=7TFBdokoT5s(XkbBoRGs7pZ[s]k;;'`i*2olK%K6=]eapN&*G/A30`..,U+_n+;Qai_1\t[4%iXHT''ABsqHAWO4c7(!sY7@DAt>rS^`LJKmC)62:KCh!L>1>M0Zplodd..Kd9 U^c=h)_c0->jP=W+9Ip=c3q]Vo93^ZMQOG:!#ikFbN[dV0*+sK]A"q^V?e2?<C.b+"dUB^3kmf]Fj-3Gk175U^\&A+_aD0G.98eOVRW_e(* k5StMMQiqkA`,tI+mH,3s0>YbA;()aF5od-c;Uj:(.d/$C=\o-lHB)4+0KiAr`>Y%A$A47US3H9Ml!/i1I=&!Gsn4T6qY/N1Qio+m$p9'F:VhR q&B>XDo6'$>e6pdh*WYB7[5`k^"HtY)0?V]2_>BWto!K599ds]mUt,1KOt=3B!lcQ'E,>I"A?O`@9qMec$5$U-5\3pE:TQ7F9+]!"p`K=ek@>,dC#O/$8BpkYbVL\*6Wi8f2o,;VLS<qhbHe%,<,?sMq\%rp`UG, 86V2T)Pkl/(`)=@D&ctDt;TE"eeb+,MQ9nHV\0(KX2_gL1ADp!=#n]`fq)+s'ACJ8d%t57UXV>@RHr(]NkRQnk?8<fj'p(8F`5\d`tN>IL0oKLj'*N\Vrq:AN)aZ!"i;e(D(`*F:_.$f',ZEg]NdGT*S.:A6PkGf0?/@dmLP^A) Jh3rjQ0-kZ@OA^T41[DLG)O0Jtg'A#G+c2^X>l8g]1A\lB*)c&bnG8imS[ocBS.AXL%K^ .*L2`,CUAE.'DkbK4LZ_@)4MZS:Wlk('RHFUO&WsM;tK5fL5dm<-G_tmh><M48CSG#aDd =eP*OC;Sr6-64e74'>aA/"Rn>e-@cKaUr#`D"A%Bp2)>#0 Y-=s-jr:ita j_jD`jN+i(GL@)Cm%o@Afc`c$66HAt[k5gOGJt-<Xl`Q@-J0e@ZMq082A]Vcb+#AhUAG#tSG!8YNLYDPh-ge(BJALNLL]jrT)LcHXf[r^=ZXL:dp'AUr%l"11^rhds/@+M82o&oa@MdCgB$eIX)2`CdR9V^k(L]]C&p:<.^;]XqeVQ&@ F[DAGd3!)q^g1*:2[\A8M@h)][7L"(X;r([rA Hf8rN&*A5=$oTo5s#;GCZX
+Fo`kMsMr*sth,dr2oD]eg<N\U4KGXn2VQ,&'!;AW&I["@nZQJWPG$PpAl;1AZ@R:DZ4;<,C-&1H7ZAjAq7LN`NV[,YDa^JKW_!oW6>=tA9q;%*^5$1[C24!O=7p0LB8c6EQ:bpii++fSJsNl3$mN#K[2eL#%d>c<39pV55VfO? t5a5 >+g-X9Yc=es5sI-ts)A9R5TqE?/<M.C8Zl  ^n"s`BDQp*W@oVW;]I'.h/b1:4!=.W%/01LcYF7=Um1(.GNWiH:Kp?Ch12Bg[5M`,TTE5TN\pba^I;oM2Z<O9%>*KqR@#RqN\;Cb99`H0d5^K*=fJ<]%Sd>i1hpA>313bbb#MCtA</sM^aXko^.Z7+VJ+(EYJgJ;j*\%5@13(Wd^;PcjC44A  I$8,VM>Eg2T*ancMc.8]W(7%'g.#VpQC!2AZ(0oW12mIhnJ-G]D;Q6OF(eon*,UL_H'UE 4Y? 1?_,2ia$K^X?R  hhS3!R5BC,T<ZN5!YZd6fQIR#P5G9=')C%:&VSLdN^\Q=(FarUg3XE_^O&Pgd`)M[,?JMA(tc@C?lCJElM>>@#rs1 gF*lPf8,*cCi:nAaE%*,qP_ofK<pL[$Mk;2G/Yp+/G1pr\l^!M.q<kd)1"Vlkr(fg;1^t-eBC0# -tR@1_oAY#7OSHnE=pt A/h_K[T[d[A-EmPnXA5VV2dAf(\"gAR$FA%$4@ TTG_O?MHmO[);^]F##V68*QQ'&B%p<rfl-LXiD[Oi3s;l6aCfB$UP,?TEArTRhX@<"d8%#K%`]$V=3-:kb%mdJi8CW_5"V/'4\V6cVn(YGRK[4odBH!?#G1^%*8Li_!UI[(4t4WjSQ6>]hZ@>cQ?A;,EH7fU]GR2p25#UA$.oE5/ETshg=9Vk_;RC#<^nK?)PKL(YCWdtBChB*T>[%;/@Rq[Alea)>Ib^QrKHG2KcbE0mD&/'eS*tX&\8+U,Q#Zm_`8?%In$FLme]D% ()6T<AlGK&rH3GdpT73OclHAtINAkXo9otK-O+;eAd>Es4q.E.\S$= 7iO_5W?K\UA2:WSgk?-p@=SQU#E/1!4.@--8IW]kLr"j;$TCUr,R,s7OlD-(o#dlEef9VK?'53Xq]/3-s!3B?Z&#3Ok&d'a*X1TRs$(?O`DTmX3mPX,>=,![AO/gEO^,W^00>Aq\)M=a3:U`AVleR6-Y[4qdj1Nl,gEDi']t&><6n0#)'Z0Ci.pZY$d1A4E?FrX9Blka%LHWMd ilA@#'i'db3# ]+Mf4VRQn6'nXg#E)I(8<5I&(lT5Y$1s.5[0tYd]IbLkgGlt%?^MHq!k!h'FP18>%"oqn+V?WX<FN2Q /=3aW@ri7A8]i.)<pP=;OJ(Z)@(kk2Yt5_?/'hVjq&n'-sU`1& BJfe9*!JgT84l]Po+=(geID#F=d-($??n#64nRW<AAK%Zd$#23 k]M-`N#T9dnAkX-$WAJJ"GjGp($L]#7h9WMkYN3Z:#eW-.0F=5CeT(K$afW!t/NcVDa*SIRV`ASWk#UnIfb8Q.&pG\)7]E\abi^ )"W*e4ab\s"V@D%?Hp`?sB,We. -tdprb$B&>AK,6JP\KYb5jIJZAG 7F"0a<l?+^R6iPro=S`r-VWEcYRA'-*)?Hn;sK<dN;B2ZRZ&EsB20,MGK34ODqIA<^D(#*Ahcm]XRb_7-jtt0AegK\`A+pX5l dcLk(K!!FcE-9CcI.`M5%N(X$)lMOAaX;8Aei1;3MS<c#/eKhS]\\X;7&aoO:S$^efs9po;[JAY2LrVMALKAXAoY)jW2+n6'?#,UrD.3Y);"?JBb_5B7T]o/.dZc\qaF5-] ADXZJM:f%F&bDZ8dBK;"iW]_U_?TeC+[*a.o[MR.$G/7^Q\fRhVa BfIhNA&Z]=;<#mFl<G$/V=#WI\cG0;+g e-*7cAg<UIci"i+If;"PRrU&C;4poA#%*GfQ>'"A"g<61lB:'^;idCr*82Z>MEOCeHqH^Se6;OgKSWR]"Kji7'1:VI)AC"nA7mhWM*okf"4,G7hm:c6B&$3CM.8fIbb[kPX',j^&K6"IoHXPQgY>@E=HE0-$10tpQ mXol_g,-rmo11C4F3b8t;@JINZ.t#TT7eG.+CjQ&NN)IqI3hE6EF'h)!f6spqV,fm4`H<PRgV5N*r3r2%sSB.9g3R,SAqV8XY<n5WR\)2)2GA H)bCIH2iNTJFY_lg%KBX22=lb66^K?_K<FCbElA(IEaX`H',\"!Z9l][*XjKscs(;`\fgDRPrVO1.1N%NnWgl;I^B__B/-Zs%!K(5jV'A!$">irb'7+pr8Y,NqR^eF_23mt@C3@MGAHm0d;3rY&+tsK(BK30:V]"gTpI=$ms8j*+qddro#A(Y64/i!F2PA3<9/WQX?l6QV^V&)m!C]F$@ 468?JD8p``2c.;]3mkp)Bl'X2PpYSi+[t<UF\X)=EGfr K?A/;Dgq)qD4.4c)7Y&PKg>Es^%2h ,)YbjfMA5:dYE'1)rb]]/j1?:Iq37N8f.>+UQ "f5qFFYloKPQ`I#0ZFLrgQ1WQ\:)L-6\$Q1UDgI!d,_#),YE90K^EY0*0saQnl48<1`(@3L%LshoA?:5Gd0,6/b0!pIibT2UW9c()EH0.+>aoE%`]e[:.A!9^rMan?\peDIlNkjaJiX-=gYcFoXXbTYD8+Sp8US^t0cBf3@I?<7&f 2%n9!]t9rF_flN_U)74!ghb.I!'D4n5dim##5j:?GPH_3Q;gB$j'qNk[H,%n6dc0aBl&>PN-X3J.[pNK 2S'oEm_dsA1&+b`$3h32%m)"QNiJIWX9%*49_)I&ARkIm:gM(Vh!$bI1iSC/;/efNr_`sWbT'>T;fNIJ<%NW0%A)]npAdI>\KaA[.G-8An8&VN6)A$o4,@31\];&k4*=*?pasKksN1=1l-ISJEY/_`=U]j[Td-9;(OFh(IHp70H!2kN/9to//b/_ar&/Xe9CmaqX:`X,S\^A+AQes./s'F:2ZMY :m H+3XS)l35Y]AicKV"G?4XERT;gD?+<J[(S*sDO2A:?Dc6?!]qOVRIYF4bMiFBo]LVRGl:L0SGI!&i%Rq<%KXn8l<)B"OVtd?=)5)>)S.0?,8X=414C$hD`@?3"Sc/s>A[bFPR^]CnN8ml`[pD$q%M,aSCC$b$#D!JN=;^9VLl>P$8s).J7tC!^LQ,c4dPAoU,M7NmQk=90>$=:&_J;s?Y$/#I^h_`%2K$[^S[7f=Oa21<Q!o%eb5FXT:E'=\8k,(oaOF#76[i!T,B`i3",0)r[-8]tkf-ZUWdKr+Sf2dM',1-Pkn/V:p1=[ @a@rRgtt79k<Y"HK+;U;l-5*JOGJ: IWH[>sm+aM=G89g8RD:KQ)pRKLf'/>$ciA'Lr7+X'%1D+6hDh@8G#+B:/_"EaEc)VPU$kLC32rR-?HCm_QlA2Qlf[@n^K'OC7CDEFI]`;C5.EQ$V0,V.<E#;<.J8PiYa`M$FYCP[8$3Dif8K'RSc@r@MF XRPUqE?nmRhVE4D<^[%5D(^.>V.t4OQ_mqq37`53H)8rAGPldR>'1DEec?"2IGY,ane;V7C:K/__[:&<dboAG@@WqJZ:3<^.ffSXTgT(X./0T_"B06!]fejtX+?"dGC#nSP\JUSFU'mS22bI#WAp\83A2T(Mah,S`@56_B\r2.1Q9=f(-6K6YZ#Gf\;o,  7.cIAMP_(5X2O("&7fr`;lO2!5=W,8`9`s/6N!+6+A!PJfWK\A< XSr6gdpo=eE!e1jqMR"ptea0A+i[Qf<Y ,)YtQ4qA7e+#E6pcFs\c^_<f0?p9bUt .#?dSj*JeK,#2QE0&9/;dM6iN8/$K%=&i[%pcCmf(;`,.]qK;nG4UM2&k%eI;9$sf-XZBajKVLE==J>-Q(Y3DN39tKGiOML4ZJ/]jY*6K("f?j]d5Q`"(!a6^EnhMXs-4(YR2'J@A!hV_VYI.'P,/ct:aiY%I5X*@<<!f2$Fd[n#8H>Xt!%`[GkeOtZa[( XBpK2#?$1UiL2i!?t8SDQ]UBEW@5SN:$qlSg'CJ>p4G44h[U)U*4s.C'ieWRf:.VF]R(Q.iRPRAi0HUFmR8GAtnR1D&03T):Hpn+RlJa>:[U<*83'R<ZrVPX-mARst:2b;nm:8`R ah-e5GLA0Go'>8Fr%W$]?l)KANM[Ttj gKAfib:.oo,D?jMTW<3DIFMR\io*NBBA$.9'8A6g#(FsamZsV[>Ml`Y&<W"Tq)i8'ROHA9<4@#a56nIM,ME'>LJ18>52+]9pLqoAIWG##HMS2`^SX$'N0dP/)7*DVh;<llE__mo^GAHFXh+,nhg[,\S`oWd!dH+iUA)Cg@qlT jQ?8()W2`0RA9_i Y;!EBdA$_[IX'ERYmL[MkeMnHN0 R"8Nhn7>%)Hh\ e7F@VP61nAQm%^$@;fs\@mrNC5=Or32)c[O6G3#OrFN>k;m0oPe/]0!.i=5Qp+Is@bJ<-cLh_.Ia91f6M+7l;+\mH7V$Ai"4mAp<H ?)6O[-8rE,S6O8'mV??t@ZF^mZ@@"eZhf6M(b3j32;E*13J*rZY9jWB=Zn[(?GU-9>-#Y(jDKCL:4Vr!h#<idLO<paCgYJdN^6rIJk_[]])O!JW%n`EiNq^ZUXL#,))es;M*=%h'#*Mlod2%-Db)MM 0OJMn95,+N]`l#5MM/:hb8V0R/n[)D3WG#@^.(#o%be-5gJH-Fs"`2VH 5"Aj/cV#ZXCH:9ko0jWL:<B+)"J`.l<8K*)-A:QX/($milWkP1L1aQR%"0GU-_".E5"J>k8<CSPU?ieVSFh<(F niAmnHk!l$\sf_=jraa7AK2de2AF2>R"*n88`WB?N)/o9KG\8A]PmSnj,=q=h!%(X+*%Z_/ApSK0`.L;*%@G22NlmG='pP%,JBl$WZ:AS)rlaK/^(J+B^6fW*E C37[ae^A]L@g$;/Ho)o)1:W6q><Q\E7s9(h`c'OTETn:!q`s_K2),-SGXf+!'fgMAqN9/N3,ZS`+`VOd9oT'@B@5ZB<Pk>GbC42!!oDY5#cMQmK3-<)(m#=s%&K37[:CU-hm->V"/AM\ 2BfkNtlILl`fPWRG^+d_9rcNQFckrMM.!3jP2V<b(:QZiAo6XdK KD5-f95M&=Y$'1hV=]F?b6E"^W.I2<7kgnUQlj;YQ'W8NFe?Pc%[Z^BEnel*gUJ:gp`7lGR<sWo*:L^,I@i9KoZ#DK_R/P.QZ(FLN!RO<DH7qY33s88-V/:nIV`_e;!=EW,M.@b!K8$g(:&dKd 1+ghHQ_)#L(]BR=Qg"d1(IaaPU#L=m;U#U;_cR6@A4CTAWnRrdMHjg%2blsYFa!,V9q^;*o"9e]j/-fg.; I@=hri190<\Ld;U^_L"G%ZtjfQor;mA/V<SE%9 DK;JB9^>fg5_YboSY$].O r)#c8_"RFR#WEt(dQCYF8h;ngfPe^Ero9^bWGha"p"J]+f.<>A`G s^Xs9s%I&aF3k(BC@WZ"J9-425-K3884cC_#0Z2 >%o<rip@)O#%A62g?fTsOAa4a36q&D3AJ!JkoSjsXE1#n12,,+n* ,d(o'Z+`;2,RCd]9[%@hTE9r8I-HJOJ$P6':P0,A<mgI%NSe 5tm=.l9eXj9T'I%al,J9A(=rRomPh3n@OVjk>&UIrn.]!F8I#*Th=17cHo>^;_8dB:>NMm'XX<sZM8$3UsY(sJ-An`L0_.!/GhED.&$37=>@beT#@YdX3DFir7"Q'tVgC2$3="Ke9<0Z/i"]":tD-/nfkbdT_X/f)ka]=.l!c?IXTW,9!34IK/'*,/.8OA`8aoXCBI)SGDZdi3b?a`%bI;nNAAfg5KXSC8NdCa(!E:T*fIo2V)8Q;j q<42ACAa.4[Y@<OX&G&JJ[bW[3;Akj&&e!.;;=)abrA2*`5TQlbpi!?P,f_eV#Tt G!rd bi-Rf'-p%U@V7Q\/I?J+mR0m/p6VW4g26;7BUG<N[UJ=U9+@IQ:rA.O&(=O#KK2dj46OP&TFFE+h*8()fLTP[2OW qr=`X;/tCWh905f8f52;D?m-BG4h=I(A]L(K?G&YK'0eI=%:%%>fQscTe-Af]R9Z!B&f@3T2^G+NfGDgHPP!J,Qi5oCC\$B@I3Eg/6D3&MOfs$K9V),ESse*!h_BL_h-mA_19@P&s3i_0iHT+8#"? A)te`srfDN:Qjr =9Q5@m&S8U*eG`k+UC@Op]SVZp7bRqca5TaQ@_g,K"O>Mk8Tkh6K%[TeG=k1P'^k4`43Kp'N+A3+'>e M>-a!M@QEPf>BY.M^D#@!8RAn&" lZp*=gJD#>l.44)c8kJ0EjKn@q4]@Y"mKH\t@=Q!ISeN@[A=q`kl;K32M1r$LV+mb_ni\;IE,6>d$t)B ABH]7&-OK7"('Usf4<rZ=KP(HgBg&TC*^@Z$<'X5<C=+P=iUk1OUaFWGOg<I_Ac$@I-'EcO]6eGc.GF5ZgC8Y jRT@J:3/#*_>U>;ZrgSANg+q7P8tFk0)r%3<-aN*%<p`FYk>`<IX2bS/j42rGs'?VYO0`OQgi8T`, r'(&F7Y<g4oA"(o?:r.*(e6<hBRF( '"$j+Ci Xpr#5Iee>ZUL-14<T&jITd+]Vlgb4/,'YE&ftJ:Qe1+E&F;>2$\*VD79cs,gWm0n+DS7bcA,c14[CZQn]kb/-$nM,K;F";E%4X[R#GGd<f86&...O.Mb+V3jBs5@hK]OH/lW.[;O/J'sa]E4'^eHRV?!l@QpA/];D2c3j\<qo%GhV=[Zb3&I;=(-;)O9m*P7'-k/Kp:NEm\OaD A\ZA[0A5r]:" %S:V%Mk`0rTs8t-U^gGBcn!om 8^-6V&T;$>pX"!h`j=A9_%pt4mZ]LJoOMh#$*nX57JktJ5HI?#ne/qIMd:?F9:q*_UG%ILCdH>fQ\f#>Y7OP(+"C'HD9a&F`'6ir+QkiB`,/EAT'IaBH$'gIAGL>;RtSL"1gO>XeX.L 1SZ+A]31S4W9T>4EJSpPk<4#("#CaOV>>iGftc7?5[?(T^qc:kl2I'#.t^6,`H4W!DfMI9oGt$p0>5f.Z>JO`^Be%q=/\eg]7MaOY:2_,]-,b!A;;_OR A5P.n%Z7YLIe^)1_$N$?&>oA6$59qS8"@VbD8bV:ON"!]`jC@4n:6eDT)3E=(orMJ<ft(p).*n&m(@gO<&[R1jce$dE08i+I=@4P?/E&(bWUdCBsK;OmWDah$02GZfA?,bY7&S=OS1LU>r+U/U-E%h*J> ]QinJS"Z`-9QP2rBF?g#8m PlBDJg^)p'Y4bRk OZ\`0<"p0#`Fq</t8\@flWcEKrMGqD-Y6;3'C<B:6'/BGq9/On3bqOa">LDRa_Md",AR>_7tqgAI6q>F\ rUP2h6P5Lf!WmaGeslT$$:km:"^b98>B@[58%Vk8o[4,3`i<A:q'ZH_pY%"Uo'`nA`#.43cb+C9`m)k1!%m`%&mseOt9o+e2ctA0Xb8dWXkl.0F'&Ws"&JQZjC1QUQf.DqldZ3oGQ+pSCX4l +Al : eAjU?!67ReeTYltifnT*HmKGP&t$Js=8ZnCR/*m-r_j5Ydp3Yr. M0aD?'P4lkVs=?d(*<BdY]jr[SC$jp_YS)j2F=AR*8^m2hgOQOSV_^JjP#sX/\A+-aQhT>-j`:lG Jp3Z@RD+o"K;Oo`cgPBOm:XS[SO/hl\%V"K%rXTaOdA?!`KL0[jil< IE9'PaXf@/tA#eT'SBZ]es'ljk^/f?i^b`k`CeqsgEah1N^_qKFOQ:V,nH;?rWTWAh8@J)AJ-fdM.Ub'>9`Ht>[4A\. HEF2YA9)_X3L^H[B`)dO UYDPi]b&C`-AD`ettad@A#nG>L4c\Wcp"a%d1Bt4"atAn_#%3>VCJq$l$>O^!?$WB17E,NMQI9hqOM,Kl#0QC)5_M%B2E"K7Dt9XK[s@_HW( Xp8-1+,k\hs [i?3?4XCQ9R@I1c,D4?]8FU17BbSEg^J]H'(3&Hist50)n$_k1ZX=$.[:O6<T_<j:`*J"-r,6PMD[9MCs;(Yq<qrK<Kq2 J>R_<AA$0bA>rL`V#&"G<PcUU"nGF[?"W"J%&'nZ3tMD,D?pgc7A[?SXo%+^=?0?FaG6ec"!m0<,H.U\iP;\JS/:dXZGG5nH)-IHaoe&IakR!hcp"nK]q@t7`#Z-1UKD.](XQ4EW%OCAFPfP)%cOW6(#1fA2hleLsX"6qIZI/PkPB,0TlRj+XZg1,g6)<;R6S)`lP]B&`:YB""-A=\O-PW7ZQ5U=IgKgI73V""LsK$)r@T[dQOqtq-7)1MNFR\Rg3hUS*XK"i#A1MPRbhNF),"n!G4AVFnsDl/,!rMD'IHqp@^Aq4TA5'gcKQ>Pi<GU 8>(Zk4\Tk?UAZ@,gt)S#c&n/KSYnFGZjs^cACm;+eP6F^)MAGhoqV4`@1%UMmfNba+"& 0sY!5$N>XYCnoO9^FI6'Y >U,i^S$3>sW3#itq3RnU@rgE1^8\UTrjTcUHbl$CFC%)UY[P:8'M'a6^1O4Y!kgi@n8:%j^P-cslBH*r,-Q"Psn4bKbHHAUVLl%F_fB\P<sD$^O&VU,5Xf';b#cibEC64s c(Wl+T+UE&N,[r6Z`Nk>h*jme`BI1EhI<tPT8'd=nFNSC\#76?:Dg-hVE!L7pL?']SHj@mFc=fH>TO9_gA%]A"i<37)\jY=sD8sYN^9XFA/Ml<+seGea<.6D^$UC[=X-4`tk@fI<aWHN,m37@@E2"LW<b *\l-lL,4OFomrX8JB7`Z<r=tOtOtBdE?[FQ2%g_I.@Ucq$@saZ*AA )qZ,[^(UCZYG*2A $&* (UTA'26U@"_(=Ze]H?i0U3W'K(b$s=&+V+[eBthtG:"E%4^;;jJR2q'1>XG]%M_h:kVC\&C#1j,`E;2[CP_;_,SHb+MHJ][=@?Z\J[!ciZMSC=8T_P^+7+4 #0aMJB#M7+J9Y(TrprMRVhqp%6n6ph[#A1N=8i>Md4<b+GoT'>mPMB$b#AdB5bdamqKn6.so 1O2dscP,`V1#sAjYn-$).Ao3moshGH`Y^-a>1T?/^VeV aR(MfbU*_)lD<ARlksCHYS6i 0q>iE%8OlO?pr$ZfBJj5#^-GX'h(lCVdm<9)q".PI$+*5j!p_'3#>\Il_VpFG6Zjia`Dtp+IWhr@EH#]l0o\`js?_);^=90%PE(m]hA-Vm/r)\W9ENd*Edn+NM,G^,U/n;tA^+<A5Y)VTN+$7=+2ij&=^i_/.T,gT^.CdD1Fs5d+qNl1Z2T*20$cnAc:sB^.?$+m(IlJae \18$h,GVofc!rdX asfdnd4&SOrds;@9][aJ.3h0=t`NnA(fim`UiZ&H '=Ic!`JiOWM-#T6QXPDcec3!J;+/UBa%!onsq92N4A':K7*FnRl=J6H(bRmHG)clO6e2CEd6,GgGO_Q8n!>RQIGfiB9s5o6`RjM[ALmTXqNm@Z:O<6NTbU`)NOr.a:gm^b_XYn-Va0`;P? RCFlYsq/5Pr%$G?r^AZAE&/d*X7AYM\AC,Mes7G -Hb0B\BfX6kcUaJ_5[W1+lp6<;T$WU=C&\hg6A^NeR%bIWE6ZjlN\:k&Kb+<V9boOA3We'Pp+PkF'h5^NrL(PC&SIg%Y$%fDpJA1Ol[+q!_>B7A6N4>?q&C-pLlqE@c)j/Ml\i'J'\/N4((UnMeLVG-?rc?_4]>TAn6!eU_:tUA?OYrAJ[:n>nrn>tOl]L,L3tb%q1"TKD_Ggo :+r<+/L<-QrHM<=)i1La%Yj<M[$U\-a6&PRZ>*#]#`akcXI$cXUbL:=!nNd4$]flE;,Y4(i51saE!5.n97EkgA`IQUb$1s_<[*SpA1j/,IYK=$^.'*J;^U1Aa:r\*[5'BfPm5i\R:Y5N7XT*fJ;m"f<-*_ ePoqPlR7d4nX0[ZP'7CSd8!faj)#/6e[R+!^]L[R:N:TNV!(Kr]OV]a<fSRWGjM;1A!UfQY! C:.jXD2k)AUFH55Z/Te`=;5\Gr'3UgmS0.MhbHXAV;hAcl1a)Zj)t]QG+:J3nm8^\)kSha(@A;OIiY[%%8ieU-cE,_"JR=4l]Lliip./\p7dYXRt\R1@5NG:lQi1nFOXUC4(MW*b+,o\MmaV.BBKf5E5k!+5tih6q+FeghS53%/T*4_R^PLV*EhW0>`% 'I-L hGX.orUtGE^39%Nio,O9MZ;+bHD?BJDBPVAk'SV%5rFKf"?[RX`W\t+Dp$)0NZ_IgY*9I"+GSj3NL[k%HI-fm9A]*9\;\>CTdiC02j0G04t_2C)XN&a6!NCi&_[W*E+K*."oe6R:Oj2/4rU6PtGm9X]s>ho)^1<44a0AT%ELqE/-UKgS#AB$kVBmie4$1Y`0JHGlRa#Xc:]60EN9KE:of(H;ElD[-b]C6hOqKdd#&8/Ct2<^WG->k1N._J]6)TUC2mWRXrPD"Y8'_,rqThCrN+A_oEMMkM5-rY2:3Xl1 @J)D=WVEo)paNT7\MYaD^:\WF6(/m:-oEQ98:]mn#U2rTqm7W07fcC6V&pFWgZ!A^-Ri>AAY?!!sY[:h8OB'o6t?3_]rM4^IfRmA$'mPB<X2,@j62V_BkPrr/6H*4NiF23S%(,EO!Q %$RLjP5X& dHpAUB h>9RjB34sA:CJ(R;lN6,kj1<ao`E3p<h7J&^s-p8+kdahR+Y@q*=<`rl6FFZjEh^OG5d9>[LNKFk4a!+V_Rh;;O><H9'3C`YRV`s4%/?%b_%E3?f0*`?[>&;)P/*^g?AAiJ`@*k?1A%p<4%9L2R:C!fReCA[f#T1C6sYjI_D/H`IV@*N6LX'`m>\qeb %'3.)%;s#s!6/B#8dd`5di,iDPHo7MQ$AV=J+V0:(\<8fZa%E@Z7)"ZlWG4;b.0*S,<"K9#CihF83rBU(&mA&5EDV,'WJ=3NXeAW3@.j2/:!+an"I%3q(9(kqZgY9h]q,VK&![P9;J=D07JI_\6+/:21[RB<D#^-Y-KhIW\TX_dUF=AfD@otfd$h))fGYlq#h\<lEMa!SAs_@+SZ`r;8E0m5UMYmKlI''BkpF:iLERQ,?tXamgrf/;%Hr^Mg0l1ZPn[q4cFoOX'\=>q#4%?Fci'2V,<%6krSb@]jEo:YMGB7P87$W;76_U"nHlgO2 o>'[KdHeIl+n@'5[+Bd.^:\Jt&\Ap\RO2Fn5C&`omaZk:sGJj&_SIO0P-Cd;G3#j(I.Z=NCqc 2%(:[0hN1FV89i'a+ed49r,f\kNa@_KE*@ZZP\GFNRNQ;"+ghd]$LgM%3U05!U-$#I2.6 GM.Cq7P&WDYj$qd`V_755b9$K7,9(Sf=6>@<R(]Q=)V9p>J9pbr+RAf>A74AV_E>Fg]^+-0UtQi_m3+rkfFFEr'<%iHE/4B7N'sRWoRIc*U_qfZ(pFqp,^'0-ja;tcTHL5:+gJPb_qrZl.X(/0TeXTVZ"4AR/'lPAsqA<$@Ej%/0XV$:][.2mhWZ]lgQ?eD8q:t>_himc#`.>6[$mMSG)7CZBZ\e!QI7U=HDoP,3)B5C7Ulm`8l&?97]9bV$) c*11'-:+% f_[-8hncgs>Na[J (jUgspZ80?Ia_'AV;n/VQ0I`\QC$>`:PG6t >1!Z%s\a(FNgB;;HbsFWlOV9<aAs^'\eZZJQfc>3M8[Ut%f/AT2]4a@fo=&HiQ$Kkle-FYl a@C8F)*S;lU"VkdR9\LfU/TT!@.L'+ZhI,!?G3A!#@-h)^!B?)c>:O8cA4gUgeE#kH'\>E:`Rn#i!@2,*)H+HVeRB,cATD8U;RsNOXr*M;O+NTMJGe<Db!OI6eErYAcU4/Z$[Ce_ZE.)Mrc=8:OS%hl.!c[67W8cM1Z4Ge.6/3CFfjm?$6!S<A96Ork]-0/AZn!U)@-0kt%]CT0`F@B.b9`3,8o"sRTPW;sWU'Sl@^FZ$^=RcfT>6$J,BI9'cg'=ei>U`gN41oN#SSV`o[8aOLPjsb0pL^G#MnmAgsb=(`-0T)4mP2A43]F!Uh\hA*V6 9#@Za_'IE2Ai;qk$JQY5>o;L)\]:h7Z)^G7#b'r-KqtTi'dWAC^g,"^i)abIli*HV@7rW#;[H.^HAVDU0)J:8sn2XK+LR._$[Vr,4Eb/7LT^MBL3gcWI7E?sZRn0YPA.\N%UqZT"H:5"Ha +4&mLinhZ%SHpL<hhc.<+2Aihamn$t14&e;M=G6)=c6hP,D:eK>CjG@EpaTt]I+&VgLL6s%+epH56Rq<iMh6<oRS59M$sl:-VHg7r>LE_Js\!*V6EAJ<m@[g2W`/]fs@W3-.LWqIB=:jc1,1YB(:0]qBBrVa;b(D5%kqiYA0p8l<V1oTY<-S&=lmsbAiZ;jFdCEU`lA7O<?aG'W?CH[GC"TB3lPt1#">4"tQerAf'c/]icOeFc]>qJahlBP61.6Zn1e:I5 r78,#,F /3<;SFor=OJLpMlGrc$]/91SAq6(c[(Fle]DE#!/r\CdaCl)$0R$4B-4bm4dX ]0#T,5#9#(`J,Aj?&_%EcpA7_aQJCpFA*F[0r;.q*f0>3$$!_'tRVnR?Q$Q"0XT9?Tq+c_9!_^8eph%AR25K>)6T%F01e/>&b2f]l+nAgmQg8kHb psX3`)5MpE1O.Q!"DT'`;7A-tWqW@P20f$$T/a>PebHtn1!qZT'&JHqr[&'* =52"&7dpe?g.$o%-kKF7q,O0.i?lc698?&86,"NdI3_=M]nkAfAt(7"*tEfQ=-K#I<q67aDF@AD3&RHa4,3Bc[e]FUa>I_0<o0q@cqtbSi'aJ8b6oEkG J=S(Ttr#a2]iN ?&EdQn\N8?m.0f$c2s29AXnfRrD0YYe=h@Q@ZjCe-a08LEl`k96Pm;B-<tbV"TjZ2\.:n<A*IAH*]W6C#lBaq,@epQ^EPI_"<RQ(7m*tZ3gfRVdE2[rolYp (b:G1:C(l@+s2(JL8pEFNE,;km0RU)GA/:St7D"n]JriFr`1*e ]VIpQXV":%co r[GN6H@-:9J5_+['9e5=d,XAB;2fAn.MM5/W!RVm'L?3EHh8/T];)\7jY3Wid<)fCaM=*.kGVRA@W1mb+q&dFAjlpU+nNr=\N@N8j4bA88ZKcfaP7sP%?4@e9)@p`oa2LKVmUKTm%Z 1?4l.rE*WsK5=B&!>q:N.0:K]80%4=JdT[F0n":o%VE& 7;;]E)'rAS_Nc-$P\NppVegCj</=2bL4E>TY>\lcF!%a:rq;9ndd'A:RY&IhG`p5>>Hj^/Wpn)<!^EIH^`@AFS3WL3P>7-f6$8A)=>0+* 7$4o63)&!i-YA,0;t\MkD(AgZah_<[k0o"0]af<(rDd%XfeBU#W/^QS!LTO[PV+8,<A(+P-d42rItI3#eVmFj&F7^as+NJ-RDht  (2FRGbRSQ_R758OHQsFWg`3FHh?jF.r31]^^`[>jY_N*bApB[$!`-QWWA#H->h<CZ`F8p.-B=Z=N-BO!^@@8$A.;" ^/3%Q<]?/b:+VlD`YsUmk":QAh/r;[7d+L/-_*/VN$`h8c"T/[ha@9 );p@U"m<k8[0ejHl^OiCYaZpLE5rnODn':*[M+/RP-GJ3%q8t X9Qp*>AJRlr$UQ<H43#THG3BsI)J0io;C<M:O5*r5SNQ&Z[@ F<G'-VtA?q)I,6hH&b4&g+OJ<\97!`N'/2(3BBpJ!\.&`@q4\^4H)+O=$sHgA#Gc]G='R<Dff"7aF+',VTNeSUi?bbj%FIk_DtiL9cK"DdmW1gr,KX>N(hAmmN\m!Y3R?nY'"`Rr4e))Ys@rQ6(FW9+m(8<6%1roR(^ERjQ>Aoab3a1MR=_]O/h4Irsl=W5+T3ZFSn`X0+r#O*iHD?bGj?I7m8IpjrFoa5J\97IJE66Ob[-4N_o,d-KP#P<rEf@]!AW"4o;D^Goel3A8a5;V^i)cCQ'4sJSm^kAM&`S8Ai!X/Agp3n3?5Ob/K7ojG_+#I&jY%Qr&k@`\`<[mF 0p_(Zi''$a//E?[a<-Wi:7Kl-Sk@N o'eCcBgHJ(ZU,(!e8,ffV6q\[[a0L5bK)\hefXm4A2s#<t6Ed)(<6K0)\7iq>mqB;G=fXB8#]1AL7.HQoXm-[$A\\CQb)f*TfEH1Q()dJ?f&qZlmRo;a%-LnqtW3e&5PgT5d;Has=F2_VI@'FrHm,WN?2 *"=U `K'P$PchrWcdt L92Kj4;kTH=#?H"cf<@iiXjA_QN^rj4qLV";XPD9j:bV01]`34N1\%DX/Ff@#XBI/Lo#c QCoJ\IZ$g(1KG2#(:XDi8A.P"d,A_68DjmdT!hT<G[=Z0H@%j]'jQbkp"q)+)g_:[AYDW,K'LPY:rM4t>.V&m?$9OAM3$5kn+,%0o>W\p<o"Ae_E^)e-oLT@Aa-acg7_9No=J;<@rA`?'!YGG8OG7D(M/H>IXT`^5!6<K>k%@p]Ybdg-7nI"A9V]]2SWb!JA!k)D#W8R2B'ALHClX$++inHhl,8AXH!U j.7%W"Z6tNSf7STULk#,b=c2Y`\M8=j>!L<n>A\i$qn8!`$El*4qXlSbfb3!aDY?2R%[1R5Ah"'$$j?8pp1qtA'Jl$%CW/KX#QcL%9a)['lmKB/(.BG]:TpH6$]M$P3\E,H=El.).V_g'G(SKG/>Z +7Sg  PKXjE]t+.WS^o8?G+9(9o@9@1c?LgS<$&?)tbb^'g(er+C2@fq_->mnAkE5cCn*<>AI/KAoGo>9TcH+h`Wd? FbbjTld6Hm+oYiT&XBq+Tb/Yf9BTIB^Ch`AZldmX'?0WT. @VSl&XcW:#(FW^.IAG(a&UF<A?aHQG"9sAEKhicer@J0`1<UJ5=."s:r-FqL+^:<&;JHr(L3T0ZR,>98DfaUc5>!o9$?$41o7OMdQN 'CCF=3n9,H-GV1:C2fre*/DfeAAgS<E.bQ^&4b7:#ChiO0/(Hq\S%DaH#T+7lYsIUS\"[Q60MRkTZpC29Uam&%?)2LniR"^$@&4Hta5=hQXj*M_EC.4DGJ0,V:>Cp#^OM0Us`WMg\KO4)#5VeCjJY-3Nn8Z+dM8HLr;&bU#`l<.J:+WdI9TALi7"Z.An&t-&SVX`XOY)D:7Cd+Ddfr!Y-0&jr9ie)OCg-)sqid!Q,>ghj*.<4]<aYpe8Z`Vad^(+]OgLt*-%P:?DMA?-;qR_g+>]ft=rY!g>i%M`] kX-bg;:*`c :*FpCB="6Cp?Ksn1E-<iQp4'(EO$[MdUB'LhkB*?DXotl1:)esp1#_CP/O7k@'eH,j5`?lltq,NR?Q3)K,]9^#>$6*nP"]JM1==QSeI5@A"1AJ/Z_F%\AC')E3ZqSM3L2.IfClYbSGOb?aeeqJU!UH_2PI2IVoJ6q7pYVa71dJ%G/foptEZbhC#'i^4tPXI0= KDT Y-TRaHabpCCf="Bi`+t-V#dP>j"+FJN/KL',;Gpj3Q5Vfn6i?8El?H4p'?A"h)A'K%Sm^r%a7-\YgE9pLcSV!=?p%(7TIdC,UJ?]b+L0LJ3PEHeXZTr].8CR?b;,t4!C'>Z&UEGNT$PlIQW6DSsF;WeM2&o=mUA>cAhf-i$qW*KB I)9.1Ae%^ICbAe2h7.Z]$UQ!@G,pCLD1J>:A#U>hg/fathk5@GnFm"/:HW)V\+\*c)m2Jk8DoKPOBc7]fSih46G/\rq0&rm#,G3J;E-*rDh sS= *C%f.NATZooQ.modqS#(%dHm;?a4d&b!XWgOmKTf"q9I -2%%q,8R4,J#$5gBfZTYMm,tq2SA+ifSo/r[#P]T<sPs5P<%KADoLC3t3T5l\d?-pNlf\80T4:jo?sq9f38r_%_-@PQ8+"U!Ab)\ LCp)RsPYNC`D.'j(FQrAA(hW2+LK)TB/#2e@CpI`![q 2=&b;kl8k6FWhGZ`.>^7eX0(.?F6`%@`NXKL=PX\?XR7=GQRsCYK 0Q\S/ZOS`W`[9W)X7V_(iTHfR:`>AF:g>b LA3A@>8dj3,0ned.C9%JHBg&lDPd9#)n\@9&p)jY]=s!9 :qp)mJ3#7,;-Nm`e9lY@:m]"The#>be)i8Ahq]g 7#C_o&cdPH13j;Sp$)0sqL`Z.WA8[L%sSPF@E-(\S\9Y(fRCOm4p#A+/.-O(a11A$tQm_(R)NjCW(2f_' o<TL."!<4`.@SM!<'b%HSI$t&j)#!<Wh ,9Oj91s8X\Cb6M]3nnBlIEnkDQ8ZRbQOc"P<q8n--ZMNV#jA`Z=gKe&t/66IcPh>fHL0$??.r'tB.`X]ZTY-740RoY&iN5STW5I Y>I!rPHtYX"Y/ ]m]QInX!&K`NQRU)A>OG5&En."WC4<;4;\=BB.gia@?>Y0'ASF+mY*2#Lb[9B#JZ%RhJ<>fc!Ae*daYAO6gYGjGl-!/h69M)#jlf86;rh<sq1e06H9`D4a:\QGK68r%_AJApp^r6rn-q$h+8o;^HR@AA:_*O#O2q)6>Hb)i)DV\@*_9T:__^KQ^l @<85s9 M6]?eA!#Cps.,Y$ e<B?lq`ob11&"+0p!0%L'*]25G*f$f_n45Rk_7\3_%Qk.TAGETBtgV3eb-_@XHi*ed>-f$32>G2bhqZA!B1LIA6@arX(5L&:e!eg0X=_bWcP-%",09!bEk^C&Y!irAW36XKqV6/MbI)Ak![%,TPZ/AKX0]*\WPq";OP*pa)Ki!,)$\1N-X$@M$b!8<;O`$8OZh_`N0mh_cs1/7&k3=["]tI-OGV.oYk Y2+.riBdRQ7k\d8GFpG/PVm.]tlq>RU!J_h'fVdeSAbW[^.iXN!f<qMX:0;PEoMR^?NslZ`NHj W/&G&!Z6a4LQp]2]=t"X]6<NEreD:Z<PrBEW)?^`KRf9Zt)9*<i=e3L8q"3d5L0'\j_PKdUYRLp069hp*/<t,R*OgK#ml^-8&AN]kS=IDMlD0ZI3iiIAj-;MOY>#;cO[m]U9NstB?Y`+Ab(IDE;'P.!Z\N@8!HZ>d>(@m"p(lS4/XIEKNZ5h:\YL>SWGK#]2OP.q;][.s$84/9FJeN')"(&q42g3SKpVUbifkn,mpIT- @XaW8j?_3AJT:Voh==X>+ ?1)iFM(aWV4]1_hI,\Slc#pWkThsicBRV[AhADB9KKPUJ`KL$eSSPC/['K8(hb?AE3^sJ7;;oEH6A8j$#1`AQXq]ps9,Ap08AYc/MO]IfN[.]7tD;U%6lh8;XH`s+'p4diRJ%oF_4b)cOH8 /J=sS"0kO<gBSc8Lf:tS5Gk2`_Ed[*XG@A#sH@fAg?QcggR_AJ&qZQ8mE<6R _A:&n0)9"WXr]aZ9hb1;JT_;OU0h[Kqdl>l)4^H.]mP3:cCoJ8V1hl+)+2d7W Dt$0'FNfB&5PlW9$M]DJE_D:(;N(?$o&d,qGsnX ;1dOdm0c.Rl^Ct/GiDTs&^SYV.PW$"J@8 b,>I-<Gm&@`:[p6h-V:)e7A-96;h8:[364n4pA5C8I3WTj%5k)'[,&4>:#.aEXL8niGh;KrT F$=M/DjA'3s5/9@r1hqn@+HYf""RWe9Afnlh*\tg\T$X6dE9C#q[\0\:dFf4!-]NS4`VIJhs6-=6e2lT5cCT"24i5G$]2n^Bb$3$,R6:ZKjn@n.A;.MEscbH4 DdA?j8O`!mM#7p (Mb(4\qBrt!VG>>(BIRK#@Z:0AcaHk=6AL-/"R+&S!c-BagoA8,om0\!GWbeO<.R":,J>2aU0%PFdYd004$69J5;\tLU!5Ym$k)$!cm%OR%btd4g`bla;Q&(f`X3:4DeNTAmo=m*:p1]Al3O5H8,'4G6c-h3;7n>Fq/)Q'@lk!K[k0:eKGq8'^Hbjj*^%?XnWb)/soo."AmJq]dI[KZDV&75oA*F:"*VWY1d`DAUtYXFESlLQ:A9c_qNT^NYs.-:rZkgJ".PD:)-#CMDPjY3^/mi\s+r67s[c@V=;W6e*^PJO9`@2fPXRojZ9Z%1+:OLf?fGi)YF]!H %Bcbh!X*+F!)/)#Eg+Z;c*f^&2;tm2;slJSP2a+& \W;9)_LH`"+S$tAU MQ+dCr^ $1(AY!.b-2ce%n.dInA;#Vipk<ZTp!@%11QGD'M!';#,H>o"dmU?'\qoV[ngS)K[\IhNC`)f:On)g3&qdb!?cQ&r,.UoSd%9KA8O!L([*H.!:j;cE7V65ae>>K)=('.65D3G;+]qYa4Nd;5l+PW ACE1@pAZ!9fj`ksP&cNdARrG dHjaQ5oVOYpEt>,V<p)n9MF3r<fAH*Y)q/2!P'XI_0.m'+PPISi+df=_YP42`P]8hh9VI5*`8`_F(k%t`FWUsFa-g!M3EB[9$=@ptPVQE;?!0CC8 i+Scs]<Ys,t*BbZ2 J89^"H;`O.8XETtXsd4L#I-o-Q#%GN0Fr')D'bg,l^]mW@^%MqYtbp0Ae!K=0TBeXY2GpWZ@n#.qaJHhR2IelC(MZ`76Y%p0$QYS"H"^?O:<Y3(M9c2_iApo9aeWBUcdk75sd+`R/_$N#%,7.T, g8RAMjc`4r0OY#;\J-+'Y2s8taO >3SV /T)`t (A(e3UG*B:$*U%1qF'.Y&@4m;$i R!&GXLANqSP^N1$/D5SG9AP@nCAr=gHZ8G\FWrDbm\'IM:n4b!oXSa#UmqGQ(=UD*99GH#2FAcmitH0)]lAfKB;T<fbN'_q=TPt.AbP]s=6gRTsAZ#aJ&+`[3'.,nkmM(M)>S5Q$tR],lh]mC$AP;D@ULc0jXAAT>pBH_EDkoO7H2_oUJ!P@01V94VqMXTS"fUAS.Vq8W7*8jMn9>mJBQE0?C@1KW>E7_AGr\BQ+q/kpCe2B@)'1.3pE0P9NbKC$`5X^'*+[69n.gQDdk!6N`c(r5CV8O[#$Yh Ur$&Z?,6iif)l0lTtGi%Iq;+L3_U>Y#*78dKr,BH6An2gR5bcap^l)Y3!c&>n<VT:7o<)r>.ee4 aE5AcSdA>MPOSQK\#=r&1"0_S^@0*e--@bKC&1Nc"P;&2Z:GGifAL6]:t%t"Y$9O#GW]?-?>OCNKs A@-ekH0m`@*!+J>,/WJ9]kt5tQC6j+V'VG<.77h*g&)+G9nKA#5TAW\ti)&M3$k/7W?A%\=P*&&L]kY&rKk!kjTUl,N6R7-cPUHak5odkeHZH9A3V/]e/;fYF-<pP^Vka]?L%Wt!> 'JSsn/16VA/c<cMH<R^q/)0e2;0#JS*Xe+:^ZA+@)L0T3EJ 1lbB1h=[9 QmbKjA&XLtea]?:Kq.jhNK)7a,bhS4;J%1oUk,]tlO*Q.p?H.tDIt()%AIRd@hS?]l4F[1!8eqI]gkcXGY9AIHK`GRgr/9G,oWDWTf\o=J]eNYPGqdFoS^/F`V;UhkT9^Z3a-6;;9XcCV8mb5-90k Xmq58-!MoS=8,7rZ;cs*fZAMb!<CkeAbep3lEp[jA#UOt_+rso4GBAt&E8rg[G8+pt6V4DJ] RFDWkE]hic+BC`XB(#,e[PrXb8N#OTM+.a$*(GA<g 2:'FJo+n!I9ng@d9oi N9R )XYP`32,r+K7ma4 X3`\4?)8dR6fAA>,(-q T)"`=2JkBj^:aT8sTp_+2o%N:b%QTZ\gnq"t4D_1B<2AXOUM;O4*Ak@I\ENSP'eanE/Y^fL4TOAcV4an>(*-1fPMHG=)$j4j8tKb`59DFSA+QR?.;n<(j:3sr33Q-o]b5;j^l<-Ua&+5%1?7smY;jbUM/7"Zf70BdK@GnRNi%\2A+%S1J/`?(NH8JFjLeJ Z9$Mq986!Pn6H8E=Eg=k)e]>^Ad=?#rpK+J^5QQsb)oT1ch=rtJrj.c+XK;Mk_e_dc ^YG[aWPCZd!n,D+1F=_O\K:LU3"G'rFViOQO`B+PP`%XRnoQg9V:YCrJjl'rh5"HeFCLg:B.Ic7r:&F($UKC>8#C"lGT*p!A\3'_A*'.InVC1n8Z@F<O&B45YQ%bA*n<&r7.WlfF@>O;Iq7_7tWk:q")I#=4mK(56h45X,q,9s.lG#mPRAAfs2l/8MBX_na39RX1B$7LKc'&?bV/'g' k_D5I67WP!W/a'l%;ZWeAH"f7AQ;OA"^*oPXQ%;8;iU46BOD>lJO;8k,[Z1W`N'Bk^0Q_7P<#K%b*cpHlEFaJMNaHL>>J(p@9OVAOb8]Djdf+69iccX jG1Q9kqd*.,"lmC3"mYNY35[,2A=oIg#`S8OJ#be %49a81hN,bj1J-ZB9MYg,p*,1gKDe=>lr'+(fb:U#_eKBV(:H8\eY-Zs4bW5CLo:PZ]&V ]tV5`';2A@r:h;k(62p]F.ga5.r%EH)=f=AlBO-d;9*;n-=Ztn1@/-,7Nm%3t"^-?+sTCNYq)pZ[R#%BRe&5EM98USIRnH]R,Ij[aJ5#GcDL1P2'U%1U4B-0pLMZ:],^f*a)tYI6->6F]]rp*Fi! h2_=EaBn5D)(F?1amaLA4)UZ)\;;4B8F8PAa#XA\=$>RK>aPcH's.cHKk<BWbJU:7&jj98ZP5/@p%_NQLhE>9o9Yc*7CO;(m<DreX]hQ>1f5^ZpkRf`5#?(],]V@j"JEi_U&+ec^F9L+o6S`$P;g':4%8Z<MZ]C-&Y)X3#^):;bkY-`MWD?WY4ITg#;T&5.PXB-F]a3[st">IGG_$22bNQ589\KG%;CdqrRWd"f"GcNj&-$QNs2'2=j6AojYZakT>_KbC4HIT4.^o=ES8*5JZ1<(!\Fs8!r;!:!@U[/oA*I:A<UkZKmV'rAjCFA7,$O?h)W XtghnUp)YO&g_sO%b&`L`TqZTi&s\"<%DbkaLEV2US2PV$id")V]d9E6-=as:T:%$."r)<#XcD2hH^S77"(gi,MW;ZDi7k@@e6YIQ\dZ"1GBHB-N_BK%A/WHnX#kan&g=<!g"?[,\!\EGsZ9@<4-IK-[Q(3N]?-+Zi(F'HZ5L\,$IE.8$;Gf4KeiqHA]nUR4)r\1dqj()?S=l&]`gfXAF'K:(&f `H<!-DqdR#aKYFFKLcbp0>eFUE.UE$^[dbN6./B(o+&Khj";/-h7U]"6pb4W:3Gd^'+82&iV6L$oar/'MR?Wo,W"@YY&)#&_<%eETG(I??e'7cRH$>%H&b/BCF"pt+97)2YnSV3Mc#`m#smn^Y9jpKoO=e9j+fnJ+/V]Fq?:kpU(tq8hX\Zl2#ppK'X.Xa2UdC95c)8D?q!AQmHL.qh+?a.PN;ZHUmo&jm]dEnA] fin@9St "5i+L-4s,$sW Kt^;[K.q2QQO`?!m\?:*]-<cpg)U6pDr]\21@-BmSIt:YjN0l3kdDB3c]"]/PIRn<'5)Wp@b$ =o"JPcV@\Y:,#[m,R;G$qdBQ&^2>j;5\Te*TYd[R*#XE?R%JJRX*gELE/ZOMoP'"i-U[8We5H5qOj30C-lI1\#MAo36hPt.caONtgNM,:8aFnFomY<fHcg[Hl8P AV!IbYROa,4^dDX__$F5)S)b2e+73K [4#q_+mrX?'YC]N2RB0U(S&QQ hOgA,AZ0`qb3V'n35LNK?FZT]%o7_G4B)+dH!WFj;?`(OA0p<tr_D)-h+-XQ:Q9,UH[4R3M Xc7#T:Fe&#h<:H23V*WWo046t0IM*G9$@%ALWR2C?ADqS3e>4(g]IO/H0$Sc3nH@nd0n)lG;+$%`nilmb*S[gZE0_`<Ab7&5h[g$Hs6l<p&6g3;54A#Z=W $^m? "RN4LN+&Gr3.`s:f98/6gD,<HA>Rm/T>RR%">8C$4 be`Y$@B<K$s&?R_MqP#,lh7?+Nh*F!&sN)b"%3P0q./&hbZ K_tl(BPd%#@DbcW&:E+eJH0,#@NU!Rqn\f9U^EZCM#XXWgnh4eIcm"Ji#dlEjAGiUt7`2^X.([Gf3s\jEJ=ZE%"@;Ibi,&Ill,[nhG0:1Wqc6"+G*E!Vjqhq!,n3RTG*4h4pl?RW(9U\mYdNrK0NBAdOFf>j$^Sdf4OY_N+C;K8]fi!4g3cF<58F-dat-XT:DkVSopo4.^ZhsjV/eX7AEPS2FVgB$'&Xh=VSM$Ik07PPW6ZO':)3Uf7)dOK8jh_f3?H(Jr=J.LgWnT1_eA=M1e,6f!4%<&&A2&DON;?=N_kWlt\Kag$9 26W#;7 crF(` K+M`V"PfX,K%Ul_d@0i!KWfX*OGp4i=EUbSAqBrLALs%[A.^,l0Al?QEaj(amk)]FBXCiYK--?0U(pfC?q!+_=@mSLkXrK'J*gge)^B-a6n'9Hs)75QM5+cQ_[B^[je,\&h0,L2:n3+V:eA6RKlQnAh^: #7oU(C74=K*?8a@iMN 6)?Y2imWkj)jL3t=2lo%-A%Gmm6AGXq_4!Ebb6`hLDF-N:dPU-j=o@5]'ibipCDlZg8,*CGk`A71c00>eW@`lpcN++U?e,n3\;Y#a($_>;^HrjD$XkV&[F,SB1n7gSqmnJZ[Id1g^sl*\E]lIB<oj:'TWj$k:erJc7cB#:UY/,soH*e[nmF5hk/+"E]31?=^CldeS;qF-frFMr]d0s8E[&`j^Zhngt?@jiqb%>^ROG<^fcY4L[M^]n*O[R3GnNg9P/XAAM=16F,A^V<TeQH,>M3/HLLO3#gZ!31(_R8kt:X2EhY\#6)+[`Q$B#C"A7-qpb/JiZ$eMFkn^MD ,TL4B?tXT&-c,/po271,` L:QjqT/q!K'EqA 6n#[#UY9n`TOWqC)=[A!8`QY#;#:fLP\"n+9hd&@S8<L/Wg?HaBIt%gi=K#]t*8\Qae71@(a;j(FHc(.siW;\+Z6Sr!A*.bSSjG[D:[SV]`QQ>&98>gA1=@,sIE$B1.F\m[c2-092XJD<`_R109#40(RH4j$j'(^%l%LaG[tiNdNZd*L1\p&tAXEZ$g?Z02SLek*3eor_IN&2ML+)kQAg3r8Y'\^UIW-h=C1`3]Rm:6]k..&0H*fa8l.nU@9a"kZS0BW6]KU9Y(_gF#p kT*6NY\(LoI+>=7e":1nOl4V"$!IZZY,B8hj6fhZ7>HA^rt'%q(_IeAAN#$#"8MFmA2qMckc  cP)2Nn9;YF3LqeBr;(\kgkAfI0eR*@.h`&A+`ESKeNB"7q;S,6E/B'U'\'1FYW[5,sBM+KgV1A\l(q.oU7(!F0!T<MI#A;:dt2WI6mcC\`WgY4fI4)O-*OT-bBsfU9k:)75H"QIg8B2!CH8),!@-B?;k;9e@L%n))6Sg?45t^H6D97\-0T%b+pEoA3(Hn *@9\5L59I.h_Tjr^P=!R>:g&.X(<$bD-DS]3<q7*PkT4BfJ!km`,/j,&=TXKS>Cr[2U?^/0_g%5=6=#cQt:]hj1O7-*[drWco:"b>R!sa"'8k_dU;QMV?:lSAcFDAaK\bO':MoAp_lAh`-" EqBL/@I)1Q -:'/=tR0A#;9N?(II?^7"Wr8-.@_*/KdAbk=Kb?6/5k /l5J:::)1cNJBbV/bC%Gf<"1r>kprV$Fat17n#07s,X$5"q5'M'%q%f6Y%r'\tr>+\UpOrS;&:N*0&?rVlQp*q:9LhNVteW"%&_0nP]CVWeWYb[mIOkkDfKdF9END]C>(/EUcC3'KtX3)- l^9"AmN>%a7htW0sKW>ko+-1p0A2NPU8ZpPV[sI'QOYe4+[F%aIY!jA `E?h[:=BrTgJ4p^1d7sAitnEHsfm)?\MJ1WA/Zim*4V-B3o'kMrct@h.>*OB-/7YG=)EW.tj!CpSYMa>CdEqFI@`1G#apQ/J4LV_VFO/PS]ZRV;s84(hSM.n8(`6LX.,jiGkF5,*UkI$H> /@ArY_7EOm)/2;6=EjTI&*#\e'#*2*>k.3T'0C*o0^#OHh[&"W6Eo2A]5GB6S,?"m$ER:Pi?aY4pH?Z; A,m!K+sF/-oB >-Xh?WQ'TI)L'mBJWWF>%mY!F&X8ZZ0)q2UfsSqZ[X:d0[4EWb!S7I(,FN3F)LdFX^3:`EhCO=U9>5.6\R;PF;)`^3M4EI/A b]Re\,*TD!C[T"iYIj^+l.tUG<0&ID.JdLFEF,lrZogh-JT-;a?2`HS7"eQ+Ng&icHUr[3kn'?nNUVD /b@7[cRe(U6BA?<ltXNL(\1rAT_cr.IH8&2GZQ=KT!*moSn^:b]=SUlC &s*mXBh-Bq0%O3RX,b:8(nBC`tYafYW]A]tJf^b`;XqJ+m^7q;nPAC@3p2T9cEOd_[J70^#Ilo-0F9s,1"K`=#?,^s!OqC*X],J`NgbSo["=#3SR/r1b4RaG4/i;]YRj7CL2nmSRk5qB6jqB#K6dAi1>jmq>ToSn @6G03!ngRd&*ZKo'Ue,Ll)_2'- h1 98UTlo@LX@i7hgRUb\trHlfc\epd$Dd'=6=tm#:U]S;d(`ABONL L6q,6lVID;;TVbZb3oT?#!cjhA#S9'J =Iie<<Ubr^#:;pOhpn.P%"P0<&C>3KV%eXg9ST cf%hT!aZIG74l-^bP>18WA:NRE,1<W;ioB;n-g*(PJteLc38\2U-"74d.Nt;:ofSZ=rTdIK*3^n&d?['Xh+L5n?C.j]T6l+>VQ>8n_d`II+&4Ume@SeS  Q`+>dmTNhhU+8=+gc/Unj=\LBal9)>-cT7]Nh_,!'&2Oa;O_!p:NEnWnKsUke-I@`1=nB)N>[)qs_)>E2r3B@c%N0R7PVUEf['eeAnFZtesX'+o>$5Y<"i?6&_Fj*<nm*UZ_nXNnnOek6 W[0ej.je1[^M?MKO,G%A0h#Wc!jZQKcG]jfmj1 gE\Ti:!7"`A#jO4Q,4!TI$2A(S;),-k Ia!GO8inSYdhSrZPLGY5m(S4:KAn(NDGpsoLs^38'`,>iY\Rr]5)>7/E\e?mp^dUAn]C3?#T'`oEe&3R5g7t[U21bj#^2t?>HAVAb)D]gf2B,<VBQV:PMU,nkL>esZ"shAWS=WN)5P.p+TZGN3\KAkAmHN2DbS[<A@RE3@aHjXFA([<8LrV%(pD+U1@=%%n2/'@[\%?E3@emR'38S9#&e!R1#T?B)b:AEU<flsK&_XEV+QTV/)/:_2YO,6nEkF6'T9?A.'?r&9VUnMC!rRjX%W9/A&53XK a2;9tcnD"Fm4k<ra0Ycl:*?IMgkgm_>V@R1fS`Ti50@R0>UdFAK1)Zi*-J0D7j"/FE0RKgkB;0iln2Vh\<@,l5r]`W?D2+"Bt/6X 0L>3\066f+6tYoOA`?=e&r+4_C(F?pZZ_h]2V0&2bBhp(=3Q,]EGTePc&Co;lFKHts'mB>=OgZJ5rFRoEQ6$W?]j$BT@RHgO*82+a[@NRqTPYs:Ks+^NG+2"2jF(5!\ kq?M9_GhBC&']rj'Qj)AhgNs#OnOQBXPO!o0&=nZ!i%DX?:cOY,2Y8#2IALK1>:R^N+o6hfqpU f[O%m6lQ%_I0=>bgAG'%\7(4Tm+LtH]Q(f[KYjRnf`W0-B'*LL- s90UE*\Ks5< =BWFKc485lcUBk(R%gULHnT^KAPiWSR6 ?35O?d<ff?d:X)7qR0&20Y"+F# 2jA>mV- ]mH45?&LV=EsoB]%)!*$'edIP"HG+V/A::SkJdA1k+@K%D:IB_ENml)0&r$<b[)qh6Ke(orDDnsEPjrVWQot<!(j%'>NS`[IdK@Tg>Jq5]_0*/Q-KIb IWTFA!SDl%\-:M7ni6Aj9j[^!L?`ZS^T47j`e`*lc!hK=rb;UG! #CL$5c(3iTti:(pCpR34`];*shFF]-d>MAn59AF1a_E2<NF57<Xt4jQKmk 'ks'DL^;mk\(#\a6&B2pYbaN-R(oKP$>>SbWX_0to6Q'":44aKk4,_OWN'WE+p9GES&eVmA!ZAWe;*qsL/ l"?l1kg2d9<5jgb5\#OmVf3WH4:$$ad*b>=G)U/n7dEeC([U<@`qL2iOVk(Dib2-K:K?Y*r+^A^,72qI)JQ>.VE SfW`"Qrg1`cJ!oAKC>O @CpG-A0t@M*]8=":inR=\NnGXpC1+<J7f1QKdi"G &GAc37cmGW'*sk!8:G:AZb=k8LcF0l&+[H=]J%m,:gflb*.i9I?=;h,UcLclokkEijJRo"]LiA "]#^bs*Qr-PeR@k9`_6Z++1R6"&99>]3lQO]i?5P-WsB0t^VO<idr5N0l8S=<pUV9]A&#(PAR+fAAo'$Sr6A5BgK#2-amroKkQAjs7'beCcn/;)!*lkA-\iAb$=*_DA<OdZ_&i1rN;6/]C"@14U>rZ8kQAh<njeqG0W`F-t8J7e 0f[isgmTg5$:#KpJ[q`""%O28,f>M+-/3'N7[h^&Rg#A%K\^9XV4Rl gZWEKgPEG;$^iRChYtWGPlp<8#\6OVm7h`lDL-V11E[4QN:,kH"\o(<)7`=*@tKW]66kb^#jiLt*/%]!)A1(Vt]%e;K0FREkVrC,XQJA'Foj:?I&Zb>^Z+4D4"A9)%`=J nAEL+q\'\F$kAP627_qJekh$gb:_FDj/*fM#1<(;qNmOX/:T&7B?EMGQ@QAs.O*o2ld' jcoHpC:/'!;`CX*#, 0M[`0HB[A5#]4&jDdoo' tf6e",o(9HXr,bVrfLCL0Aa.bjVFXVF5P>b%R(lpHU*'3XDQQWq-8MECG"t"'dj!OM[_N,FfE40OCHd6Z!'M&6f!PZ0t+@\2#)&%Pk45Vf#O<Zbbpid[CjWaL&nd&DZFr#6he(H@s]ah6W\O;[S2<>#be?9I.6D<CG0:7!l'4-HNnB/`+>kcS<X6L"SfT*23Tm`'LY4/)o%J3X&0%2R1&)qc/0O3LH':V?g$d!ho*i@s80,\#"aM;BrKe-ggAW7Ib6j^GsG\@:U8$^djWn4)8VB1->%rV/\^Te((c*l7+cDmM<W>aFCFhGD$Lh\ID5;V0a7iRq<ss]O[b<]O1FBh7:*jb&?@?)&RGF]%/C2;&J+%f=Q>dV)<],d-e>q<E[ (Zg7.D!\4EJ4[U(b@(AhmE`_OS9G&&pdj" q3PHR$me3_LRA`G[9poS)*7?L"2_qe3HXV^[%rTArKEAa:S-aOS](?hsJW_/7R\[+%;pe*kZC<@(q`<8!`&7#4.OoJfbpo3ig@50+m*eR53JRhqrU=H3GH@^KM2%<`pA;<7dUD]9FE$tYmlj:4&)lWpjoXje\L;nHsWBi%7Z8@%W2M>]WatN3e&Ya$P?d1_j+a6i$FGQe [Ho%f;j#Qt=QGoBobQN?lP1[f>fL:)H^SC9A[ ;\(Q=WAm6cp29%SZhY@(8TsDkq=l3_I,h(g?%q73K`h6-55N<Bb"<b\qiCo;QrFJc6nT`ib7p%bK]Z8Uo(27M&*.E"M&]] lBHe%8YL9fSs[i&o1*qNq$\A[-3b;`9KbFn% MU:@"4#9NFH/B`<"#)MUg^'k_Qf4rEI<!.UE0!%eTi"%_=E*?qJZhS7.2#l/]i(bnr=1mN@N7X,5(WfVX"5(.Ik%gY]ibjqG>igo3:!<3c4d]&(M/RC4(eIiBKW,oI1d4!(<;B >+HZ0)e.bs' II6_7LN#)q0a(AMn+>q59C$8oU0La]iI)[H9,gNXL4&:BUAfcT@[h'dlY4tBR90i9=:_bb?\QZ673eo0Ea?JZDAFnHn/UH6]C0 /t-;)e78-B$@6G%OBSL1a.\&FQb-+OUZWrW&1ecmcSTKW#ZdeT1+ApR'5DMSQ, 9Am& )+ e<2W.Wa?CO"X_l"lQ/Q<*[.hDltZ^6JjC[PiL2814O$?j/QC&AnOGmtW_ b]KA( 9LO*7FOICC/7dr)pPH!B?r[;`^d[\V2,^08jK/C[M3k,V78XZ@LoJf\HmZAko6>rTepb]iPgEQ!;4.c$ClmhP9 1T=6&0GBA*(Un49P<=BR:p2#p&bO!H74&n`98`_,VkA6]t dGYqeN"grDXBFk;-"dNOARN[5-%).(_NSa/RE::QKJnZG%f"PP=6#l'D'I48qT\;))GTV2K1E51o"_6-RH;:$cTB5"48AR<+U*>A7N?5J+iEFl=h2p+f6]h.fH!E0CtSO7t;SK_/h/-^ndjRX4$rfi7Onn#B$CE="L=nLG[]3HB=/ph65]@7dB7P#"MTBSV[P-60h'#NLG=klt'MR8q=d)fN])[O_`Ia-7BMX%eFAkcF6JT8MYV!)/cL3[cj3VnH$ &O"iJ_g2HosF.@ To@V7OK2"LsYYcAs5>M+d:Z1XW*e%Gm*K>tcI$W6Q<m7EInq/U],5G4#:r7W_snqr9AieIk[DsKbjR*EesIK>:;KCW8U@<iGC:efI1WKpq5*f0gc`oGC-Wmtq\Al+mGjk*8c((J7.$P@<I'/PWQ^3 [M<U_1e;3N#q,e*I>LOlgU_)VE bAQRh6)apl,gr3^#@NbAij\=Sg_"teo$a WNJ s\q8+r@pKXeJ*sh/T'M=L+QaNK!gdrAe+n+FWDCZ"d73O&/!Sn/0.[9[> *,%SA'G#Dns-Q(RBA`aO7ehjH)t4Y>ad%^:]&QOX[M[-RS5W3846J>)6])AO>s&GdJcAMo[mJfU<>YkGoI%14nSCT:feac2KYL[-! Hm.Y7Q=:(&B9'$OVjb=d*e?S5Zdm'Ar!qIRLG soR`^Z:ee +eAt.Y.FKE>i*h$BGo)I4L)L;A(P!-]ofO(X1\m,kn4&;6HQO>TAD--L"8+>W$6m'Yod<GBS 4$1ens['o\'?+TM1IQpBQP/k*mtYi%&NL""F7t rD]T(-,tU=e&hqTU8r$:1KQ4m<DqNX3""9'$,J-g+2>9bg_4 (a%XKa;;A)@t<"XXDf7j(g6/+W`o$%[@-c;ZRqq,9bkhLBa&X@(>sY^DS2fB`Aq]pm'8iB!RsL`MeG$<n%bbFG;ZT_,C=fKoAn0`.Z\6>atMf'^$hk"i[r`s^LS>(WP-?,oPj_BMIs_1gA$qsn?'oA1Z4Jf0BFg8n.[sf@=gm]33!6m8_IK6',"ZM[M>)ejl/M5S`7NlJr(^!dDiF[.n U%6S]nseSC8=_2>bcCgcoW!sAbgRfL!kgj%81")9\EUQiobP%Cd`[S%t/WV[A`T+_WFrsRlPS]gK0G?)-l)i*_X"4J,[Vl8mQb= 9Y(a^=%lViQp(feU]A`:-MU`^2tA#_mKUj<U[ln(,ai!8it:%F'1nCeHsVA5gTbn-@*%Q>SE*h,pKKl^n\bg5LBF6AiUAt tY,8kJ; B:*CQk]!fn4<&*&JQh^]rJ`k'j?PUQbR*dHa<FYHk *jLESb/Y3>YWN`IqI5d'*L%2HmA?=HK>g73Ih#/Xke3&c^@O\rHG&A1&F!VPW^2'H.[9WD[;=#!Wk267l\ggd@B3(CnV"@!^C*Cm!@8dg6pIAiaVY`omHsisq:(]e_iW)(,.3 '_Y;bm&qQXO[_c2L*>=U)U@@V6QWjlsCA_(^TWdoAjC-6.^kp/8PVmW2pMq]*<[rB(-bHH34$OB\;86lq!,hgU*m&"",6e6`dNO<;S',0jLdrW/-I\P1IJV##$>:TEl=B"$WHA0]k*cVFE+#j,%ZID]KSV=&2S=<XD\h!tWF-.maP>L(qS-;P%%"9'*IqA5:E(-H-^IJo4-*9<L[D_@F$SRC/WcRbs#2`+"a/.2'(ld0]^PMBfHHkYf42TWB'd`9LA5\>o]ogIIqd^G[U"P(ngM;AYL)a\+on0"<DIEF&RKY b4#dbB\N;Ss_eI0cNWF;S6$_N9ZM8`?4IN)9-[M A?H=9RqL"]"V30(Fn(d#- ATpboT=s  B\q&s6GkUoA 8C7.Q.`dP)!oV%I$cesctqRsMFS42&rj]@MZlMsC&$&6P]>$+A,iYLYIb]Ok8_fBRloV?h^>i?A;VM,5F5!O;mI)Dp(7"H4E+C8$M,K=ZHM3iaT?t;s*\4tZ*f-!dB\9UqF>siV<VlSi619AtA_cRe0I_E)Xa5 3aP7#M+6\jp5\D_I?$-Eh*5gIaAKH[X#_-rA%PiIQC-XBWRC:Ct^<fA$RdGAD#VN(&6l)"otBPmOtE1e=dY!,K`.FS7%oC.!:4V9ggb,W0X]]%dtHA?:i[0LKsX)?_lmCg$Z9b2V8ljqB%g/A"X6BBAFDA16s(VLC2f[:mAAZQ4kcBX%1^h>D8lFn_eNf,5In:nD#h.;fF#M\P=*J,DKKM\,pq1^`=90Q!e=,@LU-4PFS(IJm/J$0mrDUEDlDZ/<>SUO"MSWAb 3ER:/YH*ab4%E-KC g>8dCgZT2$7/5Q?8<p*T'SHb"$frE4\^<KG*A*+pSj"",Qt<M,Xdb]Y8n4!@T<:Do[P/8dIQeA@+"sD-$63g);7?\p`ihr:<\/ nf_A`RaC!]B]-!h7i1>)&MqjOj34>%m-^a8GG<j)p+YmhIaGFg[5=.Cn+To:r:$Ido$jIrj;9CIBUB<#s8oO<tM:ek@(Y@$,D1(g,^LIWC;F5]r=6Hhe"L&l]ohA9Kp)QLtaXKB-X0b6:4:L[bPb#;B.O($=%0ci#agASXh4p 0U6l.L:t<_AA72q%Y"1e6J.WqFIgq5!MDQ$C\0U`HX9hg L^6D,BGRt7 .%fX d!N:ZQ0j,Fc9 9!HBmEY`#9%bU5>*P_fF?dA5rhNmWU`@XTe,O;S)EF%,0Aj@T#8(1A%1:!?bI?U_mGggnQe\\1 1cTr:Wbbg\b 4RGo#7Tm]\@0EaI]:G>4:2CR+IQ<r=/Y- \^QC<A;@k3Bt=A A@QD,^$B$7rt9gKP4$QlsnRSU(%aNGmBsG`R>dHmOsFBgo2;1g6@jt1pC'GAaa>/HM16?i(+/9=h'-[]OL4Q0&eTGc8GP:A'>O:1-$#.AdI0Bh9aALq^#XbS:^>me<*kQ*H&g\+oAO*#U;L=M;?#!"b[^K*?iL+1seV,e4]M?p3A(=L3ee/?D#p#)2ffq\lXn;"b N]1#GMBaGDTEk:[<n-_qNHo6M4EH`3*\\h"_a_3NZBf4U?SW<;YeTUM?;ho_2;(,]`5F^f7dF>r(4ZF$j50M\K5W6NIMrpMI;E5X@I:nZH/sA8 3)#,l,1J`/8f/gJKP[h%Z5\"ir_WiH; Gi.-dF4UA+#(<t`cg<W$J5s=kj8&$lA4pS\G]FF@'NfC&YU$99[\lG.F)1&s<!XIrO&k$r]KA[*A=WGf V2r#pDWYD]!C=DUW/dG<J6a/a=FHG89&FeVM;*_\i].@;bd\Z03MrH(9SU9/QZ*Jtm)Q^6bbL)6 H4C<tOF+\s"gYp*[n-OAkRA%cVYK-;"9o\)I>`EgB$!\CiV2nfHi8bde#CNHNg20q>KZh[O)2T2+'cUU'#L>iBnDJG]`*"i>:Ua<\bJcA,b&*i3Ct02M))Q$$3LAH90I7TA-$1SWpR3JmHQ<)ki([726n)#$LJV,] k[ZnXs")+P1EUfF--*kAWRgp(e%h^Asmq_E<I.W.q'B17B\ND/M"HDt-[;51:[%/"gh)I/^b#Otc*V5tSE+b AcfWW9`Q=B8V3J.Gn3(_3E!3@^p/`V^3GX`lW\2>WK[CS,AN5U 'bgNLlUYn]A/FkZ]F9KU6OtVFV$>M*1!/q2pKO]8#:Q4'9BA@6#N/UWi@^,Bsq!R32;%Za_A-;;q+5&R4?8endVAd#"[O-?b$`E**Fk "Pl@d?3>T!taRl5"Q=GW"IE2?;81%s_b-n7jH!"VH[-Y8`^?[#8kBfN)oKgJ8?k8lA#0V]i'[dc'tcNEbaV9XT_85*(<5S_W!m^l;h`Z$`U;\rVKW:V8RA-ctGH7O9roE6;F0D*$C-(n&Do^tXcL3=$%@K3&An&/?/iFaHn6&7'X0!G0o5ng*#fHsl*_BQT`N$fgYGUC.Le]JG@NV!fAS0"WEGApT!R/^)#D]m`H'O*kPd?&kkAPrR\(3?X2lX1D'"*Q+,A!:</BMNMZRMT=QZMAgA,(WW:kr,tpU2o5%YXolD6!SO7?#9`;:PjdXfDA_ZWVB2312&rXY)k/GEQ)I]--qt A811(&AQSTQK[_ K_%s8AL^n7td8HYL'!hq^Uena/5L6M"FQUrU17qncbE0F2%jTj,e?*;RUE)R)S;,r4HBpG -OfI?2fBE(U&$_P[U^o[AQSp+BKN8P$2Q`B5YA\rda ^8tTNUr(h)4fYhg'Dm-U6%m[7^Xlta#gD#J%.mJhc#`qaG2!^r_0`cUJ>&N_W,l!H_'PZIDVD:X%1j40E[>c#3l,j,.JdXlY&NsLrL!<ZqXLS^TeAb\QLkQ-J7Z$&4lr]sd(kVX7J1#5:X0cJ9="( lF4%1J@eg2IU\dcY7QOE5$B41?BR-onR6[U'P(Rkn;k%L)"'B^YF+Kp*p`%T1Gmb?NTl*e'-sa3c5qb&6=pM#X ]* ^3WM7JP4KgG6Sc`*/TCn5[":$96sITMJC`US>Xff8R;6#%K2R(p%O$rB")9tr3-FJd7EYgTS A(\!dgX4Vq_'_<0FJ%8V_0U>)jDSpRJU0K79LT2(C2*?NnnAIF9a\&AI['B$EkH,Tt8<rKj?Nk[:Um6XeGmVQ')F/jBAR=!?)MA%@rbNhA$T)j(L(A##"8=Ap-J$k%korCPtLHoak4'Yosa%Z2Ss_TK&eiQlp;G/LAa*SFGY2#VJQ%'LM G9p-b@!I^A/dDob-/".)9LAarqp)<s DB3%dA8jD-VN0PT"]Ab6];DA]AIt/m0ec_3R"\CoNl>:JRd7bJ1BW6 imLcO27=Y)o%j4C/6;%[gAZ$k#`cWCil0[:sbU)Z9`f46@>X/\>MO)3kLnmtL^/4Q=^9a@N/n^D4sZi)R\]0\4Q9YE4VG,@d:V<V6NUq3^-ss4'(]n@;a8.k__Z7QP9\N#k:22"l+#Fs=9G8]!r:JGZ\pOZ_MFA7O=#_EZ7aNLn_Y/(;"E5j0!*F](5 Zc5edh3[Y7<=>?\ jrTm)Ra).W^YAq]-=@8(kKhc7O_^CUdZ$3ZlC-ZAP0"s=^\Q7':=+X^r%*," OZQ M, l%oH2X7Z-1;/p,f%i!'Qg90ll9cE.]6)=J-71ClLUS*D?Phg.t,`^g6c`q#O/NtWP1dHAWYFIJL/;ZbrMd6Nl=UDrs:\9D?#YHFK\ BUhIJD#A`faf6"1X3g:bkS?4a 5dY`"A6Z]+jeU1QMhcQ6]@,e"3)oU<<sV1`r/;M]$)/HUT3fp<N52-Q.l_1Dat5o8m5N8TVaip8'BAmA[g[V'+=jU2iop!WX+#+<!X]X" HXGoc'PIo5p](%7d:jM8\oCJQD>Ql59VhPq IO$3[=&)j] 6e!fY+9$Z;C)%p+csgdnAl;Ote]k !n9/`Wc`<PfNs)&S-cG9O0*^?N*jOt$+HB!3E@c^rN$eD8nj7A\mNG4'9'70<(_".;qVTM?:L6OB$* dl"tKpleT4\"H5h'1L(M6(A]Vt76dgr=S-;2*D+$`!kN.B@Hg;A^1-M. .OCb5tAS:S`_.Ijdt/T5Hqr>,9QV4F&Yq ?[pE_lG*nmem<mTPP'.2a2Q+6.BY0dmi-U$%.Jrt37@07jAjF/'6$!#taa;Z_f0[)2l"8L8Z(-+5*2s!PB9Z4K+dUcX@PA olt(IN]T3[r*q2O( gV,8 \5 pQAUq`ln#KObIiH$)Cm=\<BS0([.VmB3K0$1Hkq sS_\pl/t.GDGG%Mjo(P5/(d5'XOrgl2N8Y9s[.bb?oXoB@Whl^A%BT9YW1#'SoQA22s7_G$"QR7B+!$f`kK*4=B"9)*P'm"EL>BaQ-[+WAEL@:j@A$niZoQp*\fOtI0/peWG0>OL?Z`B?s@i_?J9<$23sGI OA.(ZQ6hotT-KjOi4ai.T*27jrJ!jg$3WWE87=8\kBD`%53Pibf[jBAnKP)\XD*6Md-nrH Lk'o-Bmk6SO-l=d(Wj"Amp!VC ,iOF8IgAb7_0*XW3o`/eXiVN3q2k@p=+sSiPVs7$1hR4b@MA-'Oo_9\hcJV7AA#it^L&S$GV(m1FWq38)d\CY-Bq)\ZaHDdA%"5-IJ\=S(-)^BHEJm>Nt'fdfi-`6%+o(qa2o;j$$AN\K=I$'FEap4D6p8,#L-8%-oUFbgAWiG[nD.g5p<%0FM:ef*AtRh5jJE=N2'fciPam'd#\@*R>?2Kr3Yn'RA)($i%$,/eo_p!8^#<[%1Q\7p!i5eR9dr9jkE#NfPej$kW,&Ar3N;4ab-a-7a,qt<ZH?g6f?jCUc12&^W=*3Ca6$Dm_^kWTr!mgHS:1t!5qs=#0Y[B!DGC]GV+."]o.-g:M(oJ>rcArL^+7<6@aO_ph;C`j$TeL^UhfA-BjjQ<S$"QY$j'\qK+F1lKi&?lA^3K_?JG2K7^-:9*;Z*]c_ecK?_Bs'@]fb6e_Bp<NIPY5X'2Fg]H8^!`P#e3g>D>Xk]n</0/0W7I/tDd))873i5b_lF8eeMgWec[/'ok2AM:CM^qgtP<+V^G+NWFhreGV*\l213MJGKWA# 7s1t?&VVGiC=1:gW`D jE5-=18,V+==9hJ<!'%N>EKF.?:ASU8\$A!@r+XLUlr?[a,@dfC_fN810! D!KYBtmVs5+#U"I0q_F^A2nfF0RE>t&P,`0V7._ajj^<>Q?tl^!#$O:tRlmHd!BejK]aqUCaJm0[Vjh/*iQ>D,-;S]XY$Pn2@3lh1(:AnX,,`4?'Z0 J)_` -Wr5?\r2PV_bA:h2HL'/?A1($g0?SG!"=:N+,8"hqI9VYfN4Y3?bS<;[p\3/qK:D80G$EUb]tgDU['[O)7Ht$c.7WT,dep*%&Ta_R,XT=n4G4M!/A.04d/>Y8'Z=Cm=,A'a!=bhRADYk9?sqics9TMQL_1?7:O6E:/^de,TXZ3A?enI)&@ir5U*9;HYV/nn$F"oJ#@a'%*,m6sHScVQFj/Hff/Nr ZP<'V6FaDYH4<8&i7ZTs/+FDH>2F,BP&BAM`9`$NTRCi7j*,a\S!>O?4rCV4]N1_$p>]E2eg aJ&sA^,T;n38Rj>U9,`mY@_kIsY[fbd%XmmD@p<rAa$GQ#X8&hXR@WWr7kT_j:fhUR5%S;-F7O`L*%PX;^j,gkb]f+0.TjNfbZ^M=jLf >7A6^<ZkgVr%$jTA'lpL&H@-L*Ar*^N7P*K!&W<l]jWT<bLfC6nL'*PATq^A)3Gric?9b:BW<D5DBXdb:)Y-E]i_g-<dkK'%EeB,qN+oI/e#6\\dma)#dGH7\>01L1XcG`&t+ISC\L^,7GYI>)'Z +t2.DPsGO!hae9L0Bt*U6D4g.edlmm;g(;=:h5:@d3k?@^!mnT%cjRpQPE8r8BA-70K6PS,#8mFp!^_lDl@kYfL#XtMEG]fe;d%%5:(>Q dF`cZ/\eA)^l.`3dPAi6(4VAf7jWV#6jfVD3.-7,$aT\ICYnB#et <i-HZtij'H?j\#p*A[skA5[3o)o,rG0B2&G<IpnV/fPfeleD qPU5HKckNI96ZNfK[0"bhi$_Vs;[Hl(s/U*L7"$"lKF+@ n#1"%5A]_5g^$T@Ni8M:=!doLsS>H#1SLfA?KNg6lPl`.0bdR<h.,!/AL[E6FNYF*:^t>p?Y!rl(JUm_?X)l>$/_!5]r.]f?M/B+HiL7Mf8P;A@iV:]'NX=K8]_^$, <4< qPK[gag.V7WHF@&ZKq01-"8g3E?]VK2ZLpmLgehF%SfQ"YM]W?FRJ4.V/G:jGpe\bjt^io$r<30]HJ"2n7H8Q\"o.=BsfZ\=+o)@B>S5.f]]Q'K4^bP3Tj0(q&)eP><p/6If-[O7ltLCP@!R[t'IC2BG2r;4p%%^37c#rk'BDQ:_:FXSEC_68"\A-J\2WNb$:Si?b\3jM5#OH`JS/Wj_1(#XAHOR0kgB/L.?Wtf.R_\EAT)k4o.C&Ks!C@]N!@JhaGrphTns7Vi<MP*gkR<f+"N6hj6b;0](MWcrD2)oK-0r"Bb7_hZO>6LjYG/,CVt3*DgB`+_q'9lK'-Tb+s)T27FJ[YR$Ot^!(W$beC?m[DgRN548N&LZ:/?sXs!F4]gFV*DnRMB`g8_X+a7qa^QAVgj.q0!rb/]OCp01ToFb%]qAHj,YTY2:PrfsO@?ajC$P(KShC T<Tc(k@sA-'Gj'><[^'gO?!f#B]].HBS`3X#p"':.l^7m^,J1843Mah@-qe*)t0ZG2l3FI*f]EU8CldM29$WUD<2m-&'B;kGU\$gsib7(8d2@&-r b=Q1Uo^rGFmaO5?iK+A,A7">b#Z6GpJk-"*^VNlaY> qTlfc5K:mCT4t!Jk&1Y<*CU$'d5qL">s#F4@%W&+,[e&G(s3%Bdil_&+d=m#oR/j%1CBn,`;\:Xr-` &9a#/A`5`^e%V-iR4X+N;Tl?fAKpYV%kWL2P)'<tB?j2QS-4Hol\:8@&N[^?aG>eB=4P0)#T+B,Ll@Gr'XZ!^g7iF liLoAG#MX*kLKX:'A#.EP-b$ZDpdgQhP5A61n:&B r_=$g-4AR(IsV*9CbiWH7Gs+mA+o^sQ?4(p"B @?:B!'*kpj@'^:73Y[[P.WoRKeOm%066gH'6B558DqDXp6tOQSsD"c?6;"h,msOpSBYjLq(QAJZD;=Dgg@Nbl/ d_$0:fM==X2\=m"j][d/Z7K1[3aGS$p 0.6ED74l;g"3;7*C'c*7U8NpCZTr$^9FZ7AWf.EA<X==C-+F<:$oMa=k `=-7fS!_qfOJciIZE18f_e64JQU/lCF9Q`"1^qX=6iE)Pk@s=OPT) X&<$!i7Z%]alK'D Dl#VCl,h_c"I:^IPNUWi$dGM8@sSr@&%B'XcqA_@1a6eMZ,)ABFo< $hp]9!R_@1daHGd@)*KXpgHq2b6FV7>O1&aYi/!mVUmC1Ya`` ].M=JYJAX#q9F'k-#:.Y<eI&e%J9LXi58=L/ UN9#;R11i.+9bD;U`(>An!foVE7lb9Ab<I#G8c6g#WoAc8?)fUh:Q^W2OK4A9b=P-sP"ttt]\djRc.AA'+Q6p5JE`<&L!#CJ,#PH'4!8qk5/i83976'Ys3Ak'&brS,HQ@pF1=c9r8K"sHs`a%]<`-g"t!Xmf7#]bpN5,C#k .\',-q$1R_9<m1fE%U\^4T7VUc,hSY8U?F2n>BTX$LlFRR&Qj"%UdbQ(2CIQ"6W$NF4P\-e,<OsZa<.P#_aH&SXJd^G+rpNtIl-4#AFM1&m,Ja$GNfoh=e>CRGR;G72S1&rFhlAOQH#85[.Q0<_FNk+F\iUYK'Kg+,cYkkO!Ad6S\<9`n`*AL:MH*-NMo %1AQIYZB"lPft9$<r@48lXt^mGQXA^Oi#@T5aRE7W;)ms"Hibk!m7mD<OZZl%2r_='"8E0:'FZD!!1F;^^co"cGA1%38M/=l&l+Q\5iOq!iJ4D7H']K+8jmBR5.ni)I,0n7PVP#0<Qfe"r>q.4K7$fiQfW@05*2M0Q,gaBYj4]Al#1EPUWAs)pd3/fM&;3C*le=YZF<IRDn9(#)T-_q K^Nr8\2=[)T6rs;,fYqHbD\Q=VLUOh.Ncq$O*2R6$ZtWXjZ 5%pPF]ER%++K[kb_AB9ei&hG!DG0\ 6CbJ80;Q`DP=I\o2/^;XI#HI#*?B=dCn#[-E4jDQ\Si5K46X4VM)$p#F?O\#'7IZcdYIg)o?fR^XGbNFPb*q[]GM)QS4b@cA*IDad[`0ZaJ.[#[@Lr+.K<hRA\JhY8"8qKR`LtOcFilqAee3A+a=j<FIE2RamDL\s5_%%X5&gK#3<#=`>'sQ!pS7Tk1+hGA2b`A'cs*&&!#V2;*;Jd\7a@S/R$8mgLpcdf](QGWYAAF;O":QIe()+[::3&Xms,6G#7s04PXnp8T-Dor6bAZQ.i2VIC!BCm&,D5j!LJ?/+M*i_8t+s6:!pb^;qM#f:)k4&!rfLUQ/-GcDq9%?$qtNFe#4:"*"IQPBZc]61@(fT!7/.T7 <t'tA<N`"UB!SdX7Wq<WO?$B6A>-Vn $2>%%,jjIb,M$`L-82!q1&?%W0qpDCFWg@U18f*%::H%sRL#n/t.r<d,SNsU&15Z/p:sWb@,kQfA[0q\q\#>!gg/?VeM"DHH6AI;+%a)h(ilYcP4<e#s<n:m`PUYmL6WJ/)ZE<IUel;ZHV]IjFFJA8=O@i\oB'T,,A?O!$Qe3plrcfEADaC%d "8fLCXlag_-F3o f^0[EhTAFd*o?bA=NiNL.m/4f49T-4XLLN\FLr&PA&:4q&'gCB<?rCI1=Z;\aTg^mk)mMD#JeY013GIlU.*DW,pM0?1o11*\N,oDGU8aD=fYhqpM&C6B1cF1;qYFHpbdgsrqX7S#n>B(lrq?$s3Rp<SE31\4UV(pb\D@eAq#p>ED3%\:o!((N)]]FrJrRO)"A)2i)t&LQh-l]WbUX=iP>l[Tf6MOoM7"f(:hfim0*@?Jio3=If%"H96(<8;7(M;/Zr!t?,=K"[aD:+6ak;,?&:;;me?f'7PGmT(B\`YmFqTaK7 :]4\Ap7$R:^?Xh0qGB$qQnjGaNR1]"Y9T4Z% T@pte3Q/??@4*p\^73Kr=s*FGJ5e!#/m33Arrl1]/1g6)jSIG:ah@9/aRR]To-!toL!hb0%I"1mJqi[H7@fT8+N:)"gCDr2\<AW`3q!)#6klf']q)P WODh:JMo!-AMX &s9ZA%:raO$)=,Sa[sBp*\`U.^^?J5nj3Z5Z*O>\Z)r([G.%e.QJ(DTm(TR(F\V^<RqBNZB>WqMk,^c$P=0^/noT/An<j9J=DG#WgDH2cN'UN<sfZ3jg1r<"i*jgtDe%_(e+*'[8R5_A^D]iL9P(/"b5c`?#ND"GGWMWY+]a $DfC'4l:dG;kXR)!>cjC,c4>r5OrQOU#M6,e2U0YcW;*1$P"ZM/1Cbl0?dQ^\A6@3:Z+-^nph]2 2tc#>6&Z@6[*B7]fGA[cU&)Sk0UgUe.<b%VLB76X=qo_:sH;f2fYgaX"8A$fVatHt$B0r70s^&UQUJ4O,<A@\sh*C7'_m%Fq[s8*DO=aE;_F=AP,bD!^e)*!C'$` P3%(C<A3-A<_d'B^(b1(H#Gl@+rgstJANe:DJD*)54&)H6AD=JY)VtJkl_6"AjQfEaH%HIaPh9DaMaD^r>FFA,'Xd`6epPmXfSsT )-iT>MAi:\a5+gl/.pP@DE%'St*+r;51hk6,/4TCUejW %7e$D4pQKGFW"r=h=a8^s.hp!?.6lI_:h]fD:i5=@m"3>^XHa\R9KU?;Vs@_%3-3>$H4L">8ljV"O:4Wje3#D<b2:2(,`RX*qj_Bm_%sOoN/dqZ?,,N3`Y2NOt2.dW8U\?OLiMXHe R/m3QtI%f)qNU@U;sfUb*<D1X6.IGq:C%h*O@PNNqnlQ_ XFfMYS4n7lH"Y2jTK(f 2+)aZVWsa9^ndABU:#Xm"oP"Z*k#/qoK `*iAd>HQBKJXl?p*)lf[K"UWl@BeAHi/q=[hF-*`<J!G[#.<;B/[o1bZI5(*:#K2r :)t(Q742hbh/6gdA1SF".>:JtCM)I7XD:,3%tZD(LV`d_>e@@>"LTS]ShI:!WRml\NG#cMosHE@t<1Z]"@JENC&=M7gW5t=D7Z'.KtN#r?fF/a[r-B20%J-,A&5A6N#<a_WmjZ(Qa@:Zf9dCb]4l.dJ[dFGEH% A+G+o4m`0#.p34?\AhZ9RJq,=(QB@gE%`sc<g%!Oq\Xt]a:^S[pIlN;[[k3BXS;!!r#GdZ[c?6*E1VSI)7WfGAs1rJs[bg(C\V++,_>K?;9k5Yg!:b=)Q,4jXh@>h$@g$GX"sH8]Wk$\qB"0*&3q,dE/a9g>*d^V8Rbrs&J[??YH"c9<@QAkj..T/nnaaPdQ ]s.-#&m/+,U0FA/lA[$O7;<NKN:M/%RqH_r[8bR>lW].`r;](S<c^\R OBUS@[U!R[-DTVL:nW`dP\2rc&@4=S3qfhVX56[:Dea(B3MYn!]t#Ai6C6J4iiL"IZecaQhHT%7MskGWcjWLZC$g\JrV^E#CBmk0\sWpb[C;%mgSJiL>62JFttJS_!I')O4fZ\4AlMm:7d1'f@2ZE-O*Xjfho)O)/:*.aQeF<tS[C4plfh3K(TI r(9sN?DMX:0#<e+N533P0XJA^BN6^l7)A)4(aDb')Sj*,2MG:*;H!aO6pQCIn.RI$F"66IL%F23<nY an[m#O2eoa#b9em P>AA,hiAFjV0mLH@tK5 '\F%m;g?AM]]&p%A7S&^ab7^5^%P^t?GKiYJ`"aBmc<g&`Wb_pJD;"C:cU6;5tg^U@dLFT2XN[Lt^o%265('rR76+;\L9WTleaf_co52*<QQANo9hXbjc8>X7Z\Q_KN\oYJ%F[G'>Xre>-"9R\O\_J*Yh&0([Aq0OZ%c&RYCWJW[,.KEo;8/oUC2PRM6-\sAqF?TXll'2^$TlX2OdR*W7PX0$CmK:J\MD#C*O:^b!*+rm6/ 6HUi^hB8%AmmS=cPT>9e;EMLUrFY6rAL`Ni]UQetHfeE-9bo`Z>!]C;$k\mtSE!ndgq@2pL@ i`m`fk#OGRcTeUgCB.'b^>sm s:Ib(j`%Q#. 5T\IldJfhF^kdIAZ,*,;8dnT7Abkag,]"-nL$nb]JCWR9L$n85 [f3'd(WTmHGr>$XeM4p&fd+1bTqE_jfn% kMPkXk- (Q7V,m*VYdCEZQrda(r1>$A><L<^(5U%OA8A&C#j+E9GWdmR0$*Z:JNpI/&hD\3cD>;@a\/)=joY+?"$%AQs?J_0p4Q<Ihck5UXW>:([Wdq#;/>MKeH4kI@m30otpY[5jAI*4g'\f0qiJ5f6V-OmQ`B^LL@AIK$or:nOHa.N`;KEh*cQSNYD.8h9H%HAn#`=[Wk(?H)?[>6=LYJIbm"QDW-4c+ES6WKS^P.?Y^>1\O6Y44l5WdA;<HnHA;SSYI&hSE%N#+/AjRQ3f)?-/i5^1[b^h+biU!9/C\Cr'[B0E>.=;(ZB";qm%i`^;mS?$6Crjg;;qR(Af\1ID\QE;cT^Bl:> `_ij_8>cK[Ut,)DhKX$NVGXl0RG`GKH+I/H'Mn#r?Y"67Pm+'3M7&FL\DFWN#qGIhK$N1>X\23%N#@ c4i$s,^>tNSrY&Oq@#N?*R%D$.!:QU^6B>pA^.Xd[i/Je+e+AKb>-=H(8jMiD2BWi%(72F>()`Te^1;b@]nKGrX1c!PjC"@q0f<RrSA9AA=o5X#[sK5pK#mXjdTWRk_>^\Ra;9r-CVIT2.XLQ\GK`/oQQZ<'WnA?@>P#*3INmY$R0N3-pAO"lRsDlts!8i0NAmC?lS"A>rdil+R?%WAg?/jT@L@@? ,3)P.J(*Ps6FHQ^lM<)J`B-K%Cr=fPLptLA'c?r.\Ji36@Tnmfb*"@gh_j*mN2EhM[]55neP1'#J[4fb!!j6eA!/jA]C]7]>mii%m=o/Y>,q^LSS9GUn$l@jn?<ZFhMIDV=5_AdV`A*UKJHeWp4#9#RDbQ^d3(L];J^OV @SgJ%\H[VJ^82cNj77pAf"sZUVbqPNF@#h7pfCJ3sQpr>`t98@ns`IbS:>mI^smC%q<Y%r,rY?\63$GK2(EAs^Td@6jg&#;T?K/0mtOl&DbiYiaI<GsE^r^8_3g9mts4L$NpQ_T,?60#'Wg98Xh8qg>m&)ms:S1c?Laq4U:YlM[>bH.t7!14F d?pH[HPBtA%9E%7m]AK4-?q'r+eL b\ZZW%j@#BpRI#UhR:FNFBY,0 MX)UD.@V&b<N-.T:nGYlKV*=46<lTV.]7pJ8ZnT[)OE9Qcn_<mGAUZ?SSW/DoL0oIr`%mXHCFAP3a9hT31a\)_WKS!d>cVAB!`\Eq %Q74!Eg7O%CDk'-fK9/49\5_ bP*M6qTENeA[A5e[MDmk7Ncj,l]a&\T>WVPZ,>WJiK'_pS(i@HR":0-T0nI\pY_5f7\9]I(!&otDqY-MRSX+th4gU)pG0KRJ)V!VGpTDiU!:9MilXlsO9K?O.#Vt("0Rcq%UaAoM'l;E!a[Lko%C3qUa2/fgC%Ako9!#8Cs!X"!fOk*(.s12S9tn`,SFBF9#n%UVYKTo=+FR#@C"r`%rH1U*o.?Ee^YH `WRM-kSJg-80T8+$ofi&gJ.0SQbUcAm=pY63?SmfL.ZL:/rA RH`-&OtN:T$-4Iq@O.r$++jHcbd^kKr33*?KYbt,'e9\GBAJ2;sq-+]r$@St)O ,H_EFUaBX1MbN*f/1W\hjrDLK"R#ia?P(-an& <7g/@11^/Jf9%]6Pj[1)6o$i.Fc#q"5+gm-3HPQ9gbLp7FOlY[j12JE)[>Zl!Eo!F#.nSdm!s(;$VL2<XMU5-Y/.O&B3S;WN%*V4IE4*efM.m8jK-VMe?Tb!O!IK9RF4"KS6+C(gAZ0_%+7;?R`mHAYg4>#W`P:.^L$0"c)/'G,H"H=08o_%^Q7J`4>Z17cX q9dWhZL:IFn5H@U,.-1;q%U)%cqFXQf^=[h5p*3C6_>OVcsm<$t#-(/g4o9 >U/T>>Le@?7D(P`R`Z)?+N`S+**I#1X5AA3IJEUa";l$>_G^4 G`\5ID8L$31/]a0V[qg+grWO*^sPAga>D6[hG,jX^W^:"!D'2WRQH+XA-AS+jOhS2nR@3b3ghn[,MH@sZQHis+d%A)=7$>IRVg+.r9.TT*ZSkmfMTg!':t7QUgk`b=(HD8ON?gf nOjj2^SPXoCV=HF_[P]cjPs,bH`r4]:2)7M[L*st%2Hlf&eq@ih+Fsop I(EV&oU.%";\0`@(;)V>2Oq3WQoh$F3:E6ai-spi^T$kjc+`rD!cWK($?kGN%?T(*]h?eO+T_E=)8B5ioL6W7<9)-r1cgW.XVf2Y3R[>+0]KiC8Bh>,C!$HAmQ1_8>2UTo._a[[qchmRnN2A^`BcgckQW]r(._m\g_gGt0C`e$GJ.r-^B"?<rB_+FM.HL8VOsmWiqcrmEXAI*>75&4q*)2CE^$F!f.;M.]>LN7P]_(^:2DLhTWH,:)A7c2sJTbDF*e%K*OL]<9"O:tWeV%]V=h)>r3!]l"pb3;\<e'dAJmXbD1-antl'2=j`NAfTbog'a/BkBY()=A?.%2ZCOmCdA;JI)3Dt2FDq_49aZ,`8qV4P>&!Zk*iUn;"A&'Wnl!=ghSC608;A@;mj8!GgAUm&W./c$F+AkA1J-P*ma>Qoqbn\;2<1Hbp;/,V^(G'c%J!8WF76%+/='$FK)!Dt>Eg""2/4m"ok<#`,Y5pdE'$&>-K#1FnB@76/(D#(pp))6aN#*;)ro'7Eea6qGsg"6qln-An'9;TgLrhd;:d9#["e@<#'AY6PeE6DnRL+jL)A7jA.qGMNN)s,_\.6EjDZ?.W*.#S,9Nq-_Y+57LNA;qZrB+4"aOr4lAbLcEA:Md5qQ.QrTlnsYJ\TH';5^F\EZD`<$8sKonrr$J&2DZ@I%Ad:FF0I)g`13t,rgm.Y8nA[.T!+k;kjd.#Ps<2JCCb$ksm0732;Bp*XjA5F"2G-e3<tMA`]ZY\$tIICnNeT@&_;X6S(f<YMfAdV=lAgLL@r6sm.HgRa-V/UgPaE):Z3GD>$rrAbc0sG0H<SkYpZH\8eeZ#+iN.$Y.^.H$G0a+lHll)qArK\69ESJf7P["Ys4ht(J]^]_)W,n-9tJ5r2W/g#"Z@:5T.\3L,.A!spDZ,O.OfrIIY2!ATKIpd3e*0ZAG`D;c&9I+G$"A/DX%X J-f+kNd('j4ND#E<;8EG1LE>bS$N)>L-Up?fbkQSjG9mr$f.,nZCYJ.o[S&YER?3 AV4&1-6#LKt7+C") \\@`B^Y:#i5gT0`(\E*Y!(.H%c9h1HkNC(>sV3XPgi$%.@YApoiOIm/=!4@,]9Y?p-5fN-f4@i.AIYK^QVgA0gI`W&*rI?X=Y?^/98'gIYnqVg[CkH>c-XL-/h]JSU_W<?Gt/G41DN&VAtQ\3E!TWn`6@hORe7-[+pf-SWU/DP.@IJR' T&2YH'_O3&[,Q.eV.U_a>l^#C5I9GII;?YteE`t4M?f6'!T k]rUol25g1I^2k0/q6UXhV16b15[cqs]P=n];5plS6BZpITMN,$I4bm0<St<;.n:3eI:_"),D&C"F?r2L?>aF'b:Tpmc^JL0/eg=Il\&:T 0JndFH$n%CUH6dCAa/+$SSGl?t/2YqPIooLf^_&/UtoL[WN/\,qn`TD\/k/-b$(!+2 TI[O@*1@h;scTFUIXHrN(+)<IV9B(SC)'%AjQi2`r9=iC)DbW`j1AVl.?j(*ATbM6O%n^PGi3>;jLZ9&oe'lo7eWcX8/ '6SQ3W4@bGC/N01^_Xh8b#Xi3rt^X1Co5OS]JrGQC!&V[bR\?++e@B:Kj:<\"#tDm*&?8bIY%;V1K,#E??rQEmr29fO!a1,hgIU)]U_6/X`6n)5rok"AXA`6,g;'p30]t$l!@.8M'XYZgAV4H%N\a1eG$Sg W!Q`WD!ga(r/tXFa3WA9mm5LMT"Xid&T.q.Q+VOrj#.(@.!hEYB*Ncq-et0bK+D1W_T2_Z-'r;d+df+7dNfC!To#[$RL3J[]\:3Ns+>?4J:Z4-if`L86=TD=M4ot8!7Q"N\+%\@`<N1#.,agY&r88.I>a5[0`DjbRiT/G2IkOpKZ`?)T8]a[ELKqFogA2P1ZGJd`(hA&A*':c8HM#3eE.sRcb#F<T)ZgU*A7g@IYe?/V2lZpKp<[qHYs>&,r[B3$Q7lZ&IW%T[h;>R;qV04CHjhKr8/O8IAn;h>M:5(((d1J5?qAS']+."p[kK<n)a6A:t-08^X:Tej<R*CA6\N;DW4QmS<i*&6Jffi 4neJp#c"CI"VKBDB?CfmEU+_RR7o70f-=A5q4g:1kAa%NC0]L1JgH[kHB>mZp1E+%;Lg%lnDsAMt;)cqgRs.^1_W\YG>A:QH<hPrN%>+1@H;\otrctFi96"EQF_m6E@W<Pd[jgHPjHsO$6*:]d S3c\:Y*T0Utr]qM`Kc'coV0Mfg-PE8m\b3$q.G-H]:>)S(oUA`pKfM@Y*o]Q3K5iCR.gec%4XOTf8e)<J+7=\<2Uo#IR!m::-% @%$;A:eqS)t( @RDj=GbAYn]%$H*;Ubhkm8eh\1fbKl4('*`05i1m"3%KGUS_G*0 _k,kTJ6X=?A\Y4Wdl]iTonCL:t)L.ptEB?Ab+:F?dRY[H=37M.JrRl"YAjj_T$dLtbc0Tkk4hRXTaAlFt/HcQ7HINZn;Qo?\P92q`si7W]WQtlC^`EN :akD;RZHn1-+WTX,h'0Z_s+<#2+_.4["s"tac_C-WhgA*gA4RGnO,2L&E8$Mf[mRiOj^!_Ec#cq_\TEH(>QsBk^J+A0rPl2=Q%1L+4j+TdUJ6)B!0IcqMfR&o`]Gsi@AgLV,-Kr-5l,*I9(==KW0CW-?Q"-WrnqM6"[%]NcPfP]nOkckft\Rj.?A;FbTC^MfgBhD- #;&rM$( ^b#)Y@;HJ#@2g@0pBj6PiOlX%A6A7R2hZPZk(8HfP+b1GB38&F=FO+%L+j +d:J#l\rl`nAbDEtdT/8@#s>l>f,t!.$L-XjP&Nf6Tqc h4eI<CH/$)j(#%LZ`?0/6Y]mbAse?pDiAaAOg'+F)@Aoj1=GZbqM]tqO4/`j JO?4e%:HFArISTng6,INUlXa&jXh.lKHQJsp?1lK('m$FZjdYm8&Xd!3GWs1AFVY='rsX=r\G\1W$ZR(;$%5`Z&RAAO?dot'im;3!I0A77D0tL*MK_ Z1bqE7=\QVb&sJH((5d.K V`A[h9d7-hhAqQnO&Z1]pGI8i' >sWcAEd:'E;:#6Js6sVS]eB9s)q`L,-1iNKq$F0[XXIE [#[mlZ5Rc06dfB>A:% <pf-"?N^  +H];[+Ko-IFhftgkI3GMHpanqiK.i> nb[n<FA[#Bj3!='TXWV6B'cJ,^0 i;QrWqq2)>;8kKDBN[HnaPpI;=+F*5n`Ttsr0<ca>^_&@ YOA:$[^t[#A=_QQ;VfHT=4Ir8\&" f#?QW>OiSEhrk @shHirk>9/berZoY>3bH<ci.:QqmDE' #14O<?Q7j+_i(jf=sW5t_Ulo^'WV[(tOIed,/9Tm%W+1bbG5hnCea!&n=sW)"jL<[2/t"UmO'+Ns$5\[s )6F=%k4R<;)@j%p<bRQW/,Mh2Z&L6G#c6a#U\(s6SU"b'EV<i0JPsF\OJPGRhBKI\,K<!EH(AOX\o@)'TE-6&.#"ZRc*fR^Jfk^h!nRXRoD&U)3JC=[F:=gD=$ch`KAQN_fMrg8m"K_ sU_0;JcM-j%13;+X(#P-.SjErga6>*PtUN>nTp`Xs7[2hAJO[H,bbROhY:RFqsVN+WtV^Ai*Z_8P_D_j?f!4[X0GJk<6O&A5'/SCO;:P+1DDH;n2O1O AADT8l,d3-=Ar*V>*IFR6.jc8CN+]s*bZMR)d,iH#P33Bq1ABaQWr<>R*;-@jT><98-^5CnO>p8]-G))41BD$7M,-hCAc'.Gs_DRC!gk>HSIHHER,+0afJ#(%9jJ`@QF%L1V;GfpAM:`;<1@Of(UC$P@(2TSLo-g)M05)F&*b7Y9o5A(OP5R%WL8rJd9Wbc0L.enUZ1F&[;ac7"!K,,NW*5]>>,X[>%@Ei37q,ro5LRs$#eLU1j&YVO\@A%b^MK._QBm;4Z2.3X$U6RZ*eOA7$bPkMd37aQEma`YiOa*QU;G6KR3X*q1G0K-Q=m1Ok#lE/gI5$A+-of5>a4\^%)$)=4-stY;Cr/]T3AHqY*,W\_K5-U/'.I6@C_A$M%G<8FD X0-s%l.>p5c7/)89RL>$-P>gtP]!YoWh?LMM!Eqtg?a,o0mMrYkjrf8?\\N)A]k#5&@8-%)RlN-3-!R;P70oq_KlO;CAAP<3JOr^sV:24rt=(q= $oQ(1+l%AK55\P9?t;BKMV>5dFHb,iG#<>#X_DMQoEZ+H;WXd;G=0+ Ze&@M\<Lt% 2`GB(+6TW?AB1Lj=2cTH9.9o#WG1I:e0$d`j"pWt'<b([?M.U]JEsT+!'o&oQdp;8d+3*%Zs)^RR5SdUkRNQ2T(:06e%T;"AA\$K)\:;^[<dmZJYoRnle';iMk&U!Q1mpC V/m&/,^!,<![=ABYWs3BERVYi4`SVXKpR7ZN,.jVg+BLX+ UrDb._$O,AB7nOiT6GAJ>A5C=B:r=1ULSDD]tHq$b2sYXAc#':I5 D"YR0=LWXee[s"f4O &-l4@8t^qL7l4UWlQ:5Opq%*_'b]j4Ik^_kH+K5(@Of_fhWAs`_D^2o]]=':KsmcPn99VoGCtCKP\73;K?l>O3gF-Ns`_O^l*e3h(FY=Ddt#M?Rhg^@`o>-OSSO&(G0Xa :Zk')</Ml\RD+r"M/Y(%Zt<k75?n@h0g>4ATV0/&##cWpG(AWj ?*kd5sqG/9.H]e%GKb*bi'Yg>K2bEcb6;fR'j=Pg1rnSL<!.=h.H2QJl\M_qD,J6g^6>fT)a?@3pMXLprO>^Uo4`ba_"i#tt'CAP*NP'Xt6tan_SpOq/Hs/N3V/PR9Y.>h(#njXVjDNmDSLEJtA$\V@C[>fcWN>3(Y9/(\,]Vf; 2p(b@$72V;  )\$s*HdfHp@j>DLD%N@gf?:_8[RU/O"Q[1jALA"[='/OAA)-i=@'636!el8[YdW/V(-d3>T;S2Oc\PR3QZ+7YGG6#d$ mS`#CnW9iANsQEoRP3ZU2q(@/AGF$8MWB:bObcRSOR'/;6iOD@iWh_M=/Q;fQ@^ P*ipN=7GDGqTC],@t(@%+1_LjGq"%HbLc9/IJ@Zl8sBP`Mc8C0\m5:s4Mj"gZ&Y3LhKI7+`m#(@r-R59\/I\$0$X!e p7W>""D(/k8OIt#3s;/0*7bYoik[F]4"6@,2'" WP@c5?l' J?J[TFE*d-oOSOTVGq:a%giE%Flg.bE626m-2i1h06BnFJULW#!20?:C(7D^9E0%hrZE&H^Ve4#j-W6<op\kV>8M\.!SdPG<,UA;M)Q -$[7gT;j,N\08e"\,;`6X4<^2AAbe0HZ`Jl]\8tN1P]-HI7pV:Q6DD7$k(pQZY7#OP-G %3co4:Bj.A`A5_iJrljh"J><-ZK^Gm.b3[QcPripbVm/EU0Fj:Dq$D`/*hJ\*8F8)'&O>YHQn6MSkmMdT^gd-NqPt m=$6iY6M7;l!l4CB>Rq2N=O;YSUi&bA8>)R9A&KJJ,A\sBCm< "'#!!I[*Vm;a4Nh2^f10r!.p:LjdF77_rg@V*XU<B`qfY/</_OlD?L:!,(N4@GP6B:S)(('TF@@aL3?t-kinE2cdC0W33'oI!%tBr?D?TK&NQ9@9^Z@UAjeOjrbgQMdA, :A\O4l@J_+'GU$lj2YZq`C1S O[0b6NdLiDVAtD9W5_]>%!t+`#/elU\2\lk.@Uf>0tR8$?qQJ_:kWKJpe['.iiP'G/,Z-L8pFOqo`KHFDsWdbG0n5ai<bI,GGX/bPX\IrM4Og4tjh7Qk6/$aM6VKpt`cbAZdfoij'kj*0\t%Q-[lhgD[,e#rltb #2KY#n#c[_oJ r8 O#/nM2=)E;JI>C?><Ha\cmVls(RBdo[KpER8%FWZ)gJ(4GKPZ7;6h\daAa?j$AA>`bVT_&"A+H\hW2"p!4E6CrV$*#N9.LL:5t<T%Y"W6JjQ+=F>M.KT#i;\bJdqR]B94)i0;I9)/;_5_SR"G4T/Uq?_3WmY*Yq%6K^dt:d59p`jeK A7Z^U=OOjHR2FeG0OT>S=mT<Q32rgqA>-A#'Yc7s s,@_p"Cb#T>.jI/9:8;cS5=jsSXE5H?(.VlG3CVaNG(*CBam!?S5B<bkE`;?\?H)LTb]Ro'1PT13Uq"HKEs)/(/6cM&O8X'p%XA;8;5bgFT9H);UYP+BiAUAJ*kXb]F?;!o% )@Omc<fjd5@]3N[mfCN*f_$%]j(q/W 1f4E`:3m$KgSiiVR"!/1kOscbi2:0B<ioZfAbaQP#B3'2T&FW"M8JqT)<6$ZR61N_WH4NP:\f@G5U;r'Vt<?o_`0dRW`kr6($A%gg6=E<<3XZDMNOF(=:3j/*LR>-Oen)\\p>"\/!i)ka$m0i,8S6no/o-glcW&PAcA![7-A3DVSAA9js5H_.%CH=XT83\Yq^+er tWe,P:FIFHiE=1K&;&5+@jj&N!]%i\Fq0sD;9cR ZO0P$4:?VT.;hFi_??dcI"pDeF4U.(BS>`oqn]VA:TksLA\OW18p^FJhqX,/F&MDPFm1GfAd_sUVC2P DUC rMl@APAG9J8+r*(JjR;!7Ddh:nN#'BH7"Apd,iKd(&LW^Q*A'W5$=/H)Mn\2a'h]OXO["oUSI"$;c]Yhds<X/,-ZW+=<UH['eZ,*f)KAm*3AD`mJOB%*4IFq9``(b:J37#SEqm:\&')ZRcg]G+\Q0t[P)#Y>U82dWk'L.ic o"Wk+<:X"N)e_DdrW1_OL0#ap []DiN\JjPe"lRaZM8r4+ag'7=*4tNbea=?;2HK)6%?tD982!sdEd*VDh,gqGpD=$j;q\mq]c=r@ .\Zo+Gj"FWL(@/4[T%TQ@=!b*<C[! .2M'*b]!Z[bp!3G#418!]SI5VMq %qEo+bTgA.tjgkC!ga3S1CYc$WNoh#fCa/VUs9RIs/TVlaAXn,P<qlq;8f;9"0!5nd78]WEHGfVa8V0apq(WA9fbl-Cqr,C6/,OC%cN&Y#]<qWD$WKh)X(.r$i5lE%Iq`t8i"`d# L+oP[RPJM:-Bh!!lrcL_]Y3VIAePj20E/_*cZWA<Ce:[8%*>! )TK$!Ih8)i&iP1HbDk!G@s5A;RAKR+JPgi\Y1jK1l&5<m\WWZqK'DY7p'PrN)egc`=`dp^*"Dtb8+/&6["^]`Zep`oAb<YBeI1$NkB=^-G#cZW;o>^50S?LMPUI]rfD&^6>LAf5[7MmdRNp?/!:!`3@ @m=/9C3*c'&=Jlb8^?o:`YhO-5GrBbqW0S_*:D6G'AcGjrds#LI!^7&RT9A>"[=bOJN`4oW7f^p`S^J[<(iA^7.$q0Ad9s=6-AcK4r?h`EXp9(`g59GJjHSm%LIU+)O` +05ZHsoZN=h`'"FOc:T;@_7CPD-TWFg/7<KsY9S-+0;2q93d?_%=5C_d*8BrBe'qDiKJ.59j,jj)$3Va/H#-r$@$)s7it_K4\GFLjRA#%@W% '^Fi5[T&Zmn:D6EEp?FQc,*R\]F,\GM*amdRBO:"lHtU $B_r+QK#KSlk:N3oq^`-Fj(PEf%BK+Ti4]RTFNgM>UUAQl^&,_)IAt(7^3g?X"1']/&b>FMD5p%bgqDHd'+a`\*88*$BeHJt K jm.: VL)cF_=R<IK^\8Pa-)mPR,n3bNE["S8>^<&hV'B <.p0\F'E;Ze?3+C/g@2-^LPA%-Wt%Mn?%PoB[r:=U48X49Tl7jDQ-WC!LC:%#5l[3b]>e0TDkC/Kqs->A2$7HgDU\Ob=*= a(%j89@-bhMa9GMka%/')S`S0@2kgA9MS!rtX65<E/8o7pAa4gPW$H+s@[7'a>JBEmS?<I#)aLQWioZ:]dB'$4lA-I-"'g/mN=OU_ NG5D[r,q;ri)e\Nei^0iX AGJVq0q25V\j<m ("o#.?sdk$XasYX7bMTdF&hS;ebA;#J)(8Q*sKDI;)]k7m>h7WqqkJToGc@S^qK7S0Mi.<iab,b!kr9Aj2:rLd'+:76mR)r9:PrPA\8]>@^WI'Lf1NZ(%hA^))K*%mlBs7VE9M tNi@9SNk4F1ah3?<`WWX!^:b("<!Z/7L,\;7dM6]a:MXdKI#Y <`04kFZIC:<Q1>rKN1`qT&[))Pa%h#?\O?s<IT_`'M'^tB9+grJ3'/<]d&Z]O.n1A WUBlaE-n-2TDK1h+)ig8g[K <]]R4(#9fM)C<]\HCZ1YdaJjX?+K2#mGha3>2#YYOVBE#jcI7CHR__T9Qd?/Gm5[tRf8tW8U'id fS@_5?".$I9)1Ve?9J/?hL:rHa>f<>qAn`Ug?i^R=2IOYq> Q-WJa_S&]S*=VhPS`-%pWptKBhe.?IMc/G3B/<o9kj1AIKN3(#l'?B4k'/+nD2Xei=ZbJ\lpm!0>#m9lI?p8e>FFpt]bT6hP,(b6o6=''.p&rYZ]niT?L(JV.1*I#qm$qGU+@1a@cL<! gk/<BlR\1Ucf79P'EKVCCQPq$s@EoaAjR7XR??!aSH!VN>dC+IF"Af(l1J6PA(O?[RbhZIp0IFooE-%j...DOF&]^l 7J;6pC2CJ,dd[#W1cA'0Xl!nH:a24**!%kF6\S[cp!PhCgTLWWPsr9lV.r_:HUD"PWti<@6R_W)LCkM<kp0cnA> `fcTl.;1+rhbXX5^=<Q_<k("Tk_4JC^hE<NgA[$drM__'$t#\@Va4LlN5A.Gq!7Wj?(T9rBF*lm\n3-+md] gr]4X?.i1()\ei=5B4>(Ke@^b')g,WcdX]c'j)@KIc\Ng'-G1@[:J%MJ0E<*&"f3MT*$fVTQ4=:5l#pAIm+ns-,:R(0q,.ibo*21jq`5Mn5"UXX_n/J<cg6c7j82V\$H1!mlYnj7M0AA[8X#)=UG+;Qm5G=`5g4*;j6q#q/hiOATs`oLIBa.p7][34AJe_r/q,N(CUMO4Seg%:(9s:FqBnHLm;Sp^HNf%fAs6/DL@GS,=F2<lY+b+4r."IEdri4J3-e$?ZCl-W c`+sdl8-'."@;dIr>l0H53.1=>IWA?Ac3_th=HtF?p-i^VFsC]c)4E!>+AQN@@\?IH*tN:NBt$^Ab=?jj;lm;Cl[>DV.MJjpeXd19lD4k28tCO)^Zm7kZ'bOjG-Jnd"A">-m;hHB@g)p8ZW.j4k^0/k7DRD=Yn0=-PD#]%5kU@eK.\H;H59XF[(hm]qV"R@"iOA1M"]MQR5, 'c2=Ph.2sbD+HmOZAp?_c]5mOg]OM;1:$_QkaS$csUnd/)e2iN4>IN9UAJ(J 0Md^]/dB3N8"^q.j'bfCjOSs-!rCKYUj#;_o$54D,Lq3H0MB?ZCI*C6.%P>ng>EW#9h("sMP8(B4l;!oe4)'&&,Vbd;P-%VH8&q:=/e_(4#4/:nNho\*6BbMqG6)56F>gpEgZK!nEWS,T?r>,ApAKD9E lr/1E_Tk5o#XUdGYft`5194^WV[Q@;jA)Za1NOQ-a"5;LZ'YB!6RfA#sZVIf(\6B\irp/KYVa[N*8m8O(MK9+JD=m;iF4VF@`7?mhKA>bdE50AVVJ6Xt_#pgZ7,U"B#=]*?mrF3MAYRfA"- N7ZDanqj(hK3T``#mfi,0 0tGA(LbPL0k0DWJ8XS82,b+*YF;#;_&6-&Q]tF<JI"C!>MafcfC/\r_QIdc kd0.o#^clX.E=3<l:74As,mM4A>'B]78%oRLUbCd8Cdit^GnMsE#pR:=qV0% skgZGnOK:scEd30<*f'dem[/<I$O_``-EZ=92ToSFWH7*J3o5<!J(q/)8q/1=YVRBh\An'7t].l%shN$tJ0p>$!B!jS<c)"!AJMYn^tf!jB^]W[,6hH$/cBilFHDo96OhLRD-bi6;;G#6B[N`KWIts7?3Jg6 SZ.ih<2IrIS93OABMd(.A\d"8KoWECE8_KZ>RZah// SC29rRbrk"!A.i%[!Zlg:&O6%iWnM9 8^e)K$` .G-."W,QN2rnGm(V'LEF*IUT1pmH=iC$@jp!D@&C!nDr>5FOj^N!5%Q<(jF@5<1N7^s<H]@&h*E(La )=cS6P@O[%_n`j>cFZ"ZpkQ=UKL`QqZH&"6Cp'(Q,H8ooqZc.\WEl1 a<GHjI%;4#!Of%KUc\T2o ,))^fP#[OhPE$(3N.hBU(Op0'?$1*B7"I)R^IA\8_G<*j6h>UR`><5 Y^l,ld/f28MJXjV&$I&T>$9g c[K"d\mc7OV#Z*Y$M?`Q(QY\,_\/@r5H \McYaaR#CV=JK(A*.LI_aRAArY?AjK+R= Pn%t'3dX&ZJ-YA9p(q')@2F:GVe9V+7j.]pdMrT QF1V:$*`@.?atU6Yi;0+;oNA_'Va0A38-sf6#YZn_J3WIfF Fsh(TE64S5-=Z/L)#<TWA<e/9Z<dh/<r"o[B;"I[EFh4/96tL*D1K9Cn TpCk_?lE@Xe;bdnlE,Um A")0$AF ^8W0O$oX&?BLh78NfoP%`!aa,kE#S%DW>J7S.Hg_oYN_e--jU2oaK=peMh`Q[$D)dI5q3tA7VDD+,?iG=f*bs])J/8;qOam0mcO$FXp4jQqN!iMM'KIE:l+He=U[8o/9/sLtd[c3oJ%:Z5hVVZ"dO1$;idosN<MhfhQhk>Dg,(A'F!NfeY^O!akMYg*SM??f73PL6.lfHY`r_I]-`V;.\A9j8h0*Y73ZUQkqo!Io%i*+hO.G@,/d_%'FO9dP@^D"l&Qe*-[$!^=X)tKAH$<sLrIm3lmOC&m&+M'm^.*tK3Q4r@[Irnm$tT\=\(r"r3Q40F=R(Wh2<`7YVrjP<mXJ\bgr>:TAK4KQ"MFTAk818%GnKgdSG]J4p\8K2ZN".1om'PN+i5)lI1lhK8ik#m3jVY'W(+!%_n*W@.KUQ+Tq0-JE -7G#gd:ARilZh9/>]0,_:kTKm!F_oHrV8Y<*]D4'tSieR&AOkf_?J'/o:qPdReU)LmpB j?;In4k?[tAOi+DZ_7&<2GMK76BM`qMUc#1#^Xi%(H1J^OkS;a/^ANh8e.=-"J.f0\P$,h"s/,sW"Oser6QcaCK[D<^:pbTZB_$q;0FT//eqJj-%KFO37,%`6kg6B%`]M?"8cte0V\*W#&WL9:5a+,-(h8`;;D*I@:ZoS%9(oJoYfGoSgUJN,N15"(I/G?G$G.t#nspAmaV4KoAIEQbi-\4R?t>Aq6kVE>3X"XFVNn;<:;]r%'p_N[pjjeJ]^W :(&NdMqg"(!'F*PoO^!\f2q!S]\Thf+s;9AI_3-SA@k>p/[Ah'WtN7=#f-+k(+p5]e\^jQB6-rDWMAb,+K0d=WmR.><:Xsg(fR\tMOkh!5'L5@BsTsGMd4A+[ZSZIp%/$aPAAc*A>I"h?d:^? G)snhb2eNC[(J8=I-e.nb2lLLQ#TVNLli@WnK`PXVI]M[ki^r0Se4?W_&9M%)\]r/0lcJD[Rl4rI2qG(_]^1,`_RJ#YA&Y3JI,eHKKG@p2##LQX.89hjBo!t_,MC;;I!TWAp>!sjf.^,+sZ=Hr%N2o+cSk.9lg1d!]4#MX6(]ReFA=!%"gqCc-MW<TF<*\7"VG)<.WJYbD8\hcpDkbG%6cETS0<),EKf.W9/g!Xat@lDs3)o'#mc^H!S5VIC lL0Pb2W2(&krB9NOK$jLSe=gA%@qO#$7V*V[L`AFMPLN4;Mt54:A/%sN;]snb_1#^rVWOAA$3V7SGF?.<o,! b1W+tjd'=q^g.4*Y<f&ekgZ$T<tE.H.)3QpoLD\$aBatR%P-?("5^]>,8#C;c=th*btBtJap]K\^+lV?\>[;Ap8<&RsH8cH`#VS^J]?gIJ5lo'9Z,GC@f,AT(>^dS2StQ+mNQm0e`6\_:)?/Wr?,_^'ea6XtD2fY3$hTp?eTdaG<+,!fsOW1-^B^4:8d++a'ra]JQkMO9V#V2@U_YWLW0L)OSU is?CXFt'5KA:p3ZY/Og!=ImOhfIR4@Ebg3AAXGh-Xkr>!!?CbmA;M$=]<'C[W.i=B+s4"RG.)<OA?+3C3# G-oKV=^gXD(V#U\UVDWJ3jh:[C4t^3P0l1'kL6WaFX\IGFn2"qG(NJ8E_p9Vbc+j6BGLK8g2I"HI03YMa.k2J7_Wm;1)4chr![$5D)jMAQh(Q56<7CD.ad$,lMkXDH$lC2kgP9YM>DcBm(Q7PB#I2Mia<ZLo^hb8^^>Ys?\VeitrGO4@U"ZWW+>5V8/C#.hP(`P.9,&S,8[6IO?BUO.oU[*OAmm("Z=4_) RX>'AjKETf+?Jt`28%7n%dnU3bRc0=>PnWVZ0_j+/a5&kI$G_=Nk"nAPVWhe0PV*tIZD&*-^]gpV0E1P4A]i,DH8j*@-@=W9'B2DTA\Q23k$K./AVc':YSZ?%dQ9[d!i58q!6$qP*J-.i5JAj1[1J_`lK\6pIhQ`;pA0'"XDL0#0oV;N[mZ)e$qTtNRZb4AGH$S(J9=ACXY)jG%^ggr@%IsTQkk:ThT`@^qJ8[]qPj8$.lmTp,H<71TW@ASeAY:q.[0mZ5N,sA;VkN=6?j$E`[SPR 3n*:ND1c1-L1KU'-WPH6QA+/E_bph'83j;eG**giUl6ASo[]7m2[^T8G6jUUd@prbCrAOVlgIU[9_ch<mjMA@0r&$6Y8f.fm,LJ=Ki^A4G&^'r[*b'[&/F<>Ge;^X@ T.a:+&tptA0%5-p#@#$>r5T27#jKEjFHtS15pplmSM\mO`"FsN)d2jm9KKme *OTa="`gABf'/O=2@,e19XR&<8p:1L&U,(@DBYcCGOIeD<i"RT)8*M"R#%"[?"PE$4!a@630<Ib N[oP%rQ6_Aa%:/B=;5^-+e(s9]9Bj/&hXX+XK n.ai1k%^Yc((gD:6qTA8O5(j H0"'[$c'XIX]_FGdDI$b8M7&f!X'fi>7ajB<-fbp'\V>q7n>o8fBkERO\?Q4ie#pFb eSs)QTR[pd1`-YS=Jk/9Y**^`p#YPQENmk6UU-"]E'ZP?^,L5SlthTnc2_lKd_>imUpXBVDmRbd5r2-O?G8;6=,.$CRM<KfVIZZdPeG>UdZ9RVs'oPB *U9T*&Hkf^]Rn#VHLZqlh/JJ&Y`At `hPB&TR"an*#.J0E26`+CW=[s;^?%gebsV+[^`EUZ'aFMS!NjmB<oR8]8Agi">c cAG=VO+]+M[1rgR-?5lOMiXm^@0X1"7j_=A& Je2mMh_>M'mat?$)l[S'YjOsH]l ek+Ls5l8 cP,=`MW@m UoEYnV^MD/A>4mN=4?S/Jf3*>f%V)B@(;A$Bf^IkcLAq-T(f]i`7i6Xf:%=0U>X[+'(ac:l7o#[Pp;;`&D+CLq:U"/k<";m/K[E/L"23TMi(bf2L6A0'D3*B1 U.-]Z3FHJ/#@9'V5<U<[#q)ss\;/h'q0PYFh=?L=]W:\b%I,bdps1\%17;.eWfMm0DD=;H3hXOet'6/P<(/-O]8\WRC\?-kklr;7XPBg"FNAGZt5M6&`mUHgLI^^/mG7_5I7e?<baYm_"q$/NqMU5"qMM-UGFaHDc?H8Od>A;Tah)q8)4]JBp+%7>nmhS?e79@Iq/C*J_5r@9_ZdsVc5Y/k`BkgialL8::XP*%V[cg^&Aoje_/c[ms_4<MKHE8:4\X_.TrALSj=1>\N3`Xt^(KCneo>^ogjDh,=^/RP'-=q(!%[B54UpT,ic%K+RcrXP9sKD(0/m%>ZA:s==@cAdm`aT]JIC63Q0209[%MM;9:d.`tnKqFhg,3(YO4]4 =@&[?%6VWTA+K=A%`S/[jRA/rCA3#BBhAdn D8p'l/W+tiilb;=^'\GRM(8b"I.[?*VF,+%1"_#J8mL7EYJ#1T%Y3G?K^57Xmk(TQ/&Ajl6^mhsR0CB12Q@$(tBiE0YB)Uk;A@'tJYCab76t1Q9Ta*0f!AdV!5!3%;K!<GqsPHlAZYHP6^1``V\\C<Wp/s=C8MAO?ER@:Kn%5A.Tn[B^6nZq1WTLl2?c`lMHF5_iiZ;gaRT1!WA>b<,N&mO%TdK 4bOOfn;m`I_/<?>:nHcOq]Uc:3ljjJQop8strF,cY'Z?ME[`ps[+adMHJ2A:?)ffMG@OHf6*,W(kDNM:P&#"f=)e3h%4^]f=0T]1+bapD=A60M&l'b^4HU\la-I-j<`A_"/V#<Ab7Jps#[s8A(:9Q8#hDAO8rVTZ]cT9&^QjY,4T !:N\#"apZcAn?&T+f$"AX^X0(t*WAQlIc[QTbT%k#Ei)Yo\0a%90(J8fDQ)qnrr)jgJR?L)')0l?/$KoY8#N7r]ekrqIHHj?Z0HSK8NV/@pGo]b=LF?N?CA+5:0VJe;'?=hc+,0k;H,A1E:O_K+2Y.H"?N-`XfWfRW:7+,*W2GpjC]n*oD9i$Dh"[7OY<6n*9qUf0q@pG+jDa3Zm2o(\9H&fpVa/9H.3;fm]JGeYQtG8Zl5[[KkZY6f:2QQA3H=.`;_66IWsh,AVKml<CGB7/&QkF3dR;;@k\5L_3B&;QG8h'O_&].=h=#n9HJJdCLA`BJ+9T96 aAgN 3DNN#7[XX"E<ejGt:.'rA&].'-[=HPG?D[WMPrPcQNbm3a_.=]c[0LB?JT4$j?.`s-(9i/3WA@rmAi<1dF!$*@glo>h6r)_Ti8b)KG.K>6ECdLQL;d`<t1#K%+kgDC_'le24[qs8T;"a?e2c&]XQtJI16 8ZN-pGA)AcR'M0Z0qG]CGN*eMcCZUMRf'Jd,r4rA?f%=K4?DPK)%O%nMNn02>VeFI`8=)`Q<EC!$^.`I3/#gd^l77:8Z9bN2p,m,TVF3P]%,,ND,>h0ejFQjJckrf,><6bBmIUJ+rZ MAs)AJ'*[qSIC_e=K*1P0G.nW_A]c%)H*HR.-.g-oO7C N+Ie%aZ]_fDW]:S.9TZcXq3*ih*a)U6k)iqoXs\"*dp#U&eM%A6mVd2[bp&`r$'^UEi&jSsWU,OjYX4r9$AG*r^Db71Ul1M9m8g6+s) CaaTI`9#b)U1AOY3ALhtA#q\_+]PE2TiW'6aZD\HdkD)/U<D&l9i'Hinl[%5/S'3^IPe\$(c1]PnfGtqWV"3oqjQX i+9A+<qe;gAC\$ONsLdLr,G4ikN#RG+#$A,G!hV@t-8Gk"*d1Y>p.d++A%I^#fGKAW]>CtGt@A.Qj%UKZZHNnXer;a(&?Bq,]W*ot]P9e%iZ@]lXcdPU(h#TA7HGT.E8R(h;EB9JT15I]q)XtH'h[0IjLYE=/RFFlcVS)&GK"[Ag`+GcdI?tTD,_XG..XfWAl)gT)7dOFFs3jC#ctjk"2lpNM!Ui0$5H@ja;XZXDT\FMh-m ^D%AIc;N5A<sr$+1Q&[GsOUV77rQ"t:$ZXPqDc3l;7H6nn0sEUbd!Tp.rP8'B4:Hsc=%^.bmYfs;jgILi_=0L/n(@;dPU<_U5'b>.j%o%"a>#'h:kjq-Al`V\]Ih H>:F1hd,tSoPac]sc\'j:4\Zfo<-%foa.F%XN@]ZYm+SIFi3f2)prdB/c$U1)["WitMkFS5N?=b.\XXf4D@[A\\jpg8iNkRCch?pB@R3$:G!X'O%-B!HRanglMWA#5eaF2;a 2TCs_<CDPW_>>cEXqFAo7-<l$ ?4krlJ/q]K\Y)j_$AdU"3'P`AblRql9t06f8(bRC&*:[#E5c6cnNWAQgS7aSnn1X7rNM<c-tV+Hpd`MN$R!AL": =LdPZ[D5mg=%sD"TdL)m;AaQ7P_-9A2s[.'TnY'6"C6aFL!a"G][8>&Z0U1iOHNSG BShrT+_I.=P0:S]oA[]6&,W.`4_+#j5G7Qk+67og`SA8X5RB1)K9WG\go0C_ao<m$^:m[JAA4RiVWn_V`c/am _]F#-;K^ HV\QBI4UD()0+e>N-2sI<b8G)2V38bA`?:\Js*gE)E#3p@_Q!\'Ghk(?!ek\S=JFB+U_P0?Pnn<qZMQY+M+q"[+Ga^<<d25 Z&SUg4PQ3F1?<KG@kBY=sQ:EBda_oNV<OF7D03FJ` /Y)D3m1d[7@JPj)LXn8YknJmPGqOEQo.AAPCI;d9*<3eIiO98tl_[]m8LaAhC';5`ta2<H8Y+.*%GDJDA,6[+g\@dc+3c[D:B:C;jr-0fS6mJns=D%G'Gt@Lo!DRPV*!e=Go/,+dP>8bQ*>P_NM#%ie,fA31lW[sYn)Z-r#>4lA[C@Spt9bG0YQt_;1$V%O\-Srhr6H?jM\GX"KX!CpVK,)Z)Sa/YB6&^i4TpU\FNZUgPQ#`l5jnK]-.A*l<](I1T)M mQ[TM\;AdEF-n'*f[o&=$SD`oD#*7Kg#R?0'N=FomX:N"m$rM <qFI+S_jg4bY7pAf=UP6`2%?l6Q5/U2dH4_]^a OI@JZES6Mp<1Mr6\[(/J\b0MSRHDh$6pHA![3r^#M**XHJo?X]%E`Y3%6E(BZbmUht6*di2T$DSSEg^8fI`@D#/?:"IMNW]`Smf$2&R/P<qoX]sHKQgCQsMpQsKF4'cgTh\@DZ;SkDGjm_ocfF_4qcWn54/aH\)F+6EQsOOif4sa 4Q9'LTK_e%]HlDr#tL=\akd0A(p*YLhENc#DNA(:t84FYn'<,Z0/NqP4E7#XD$T;>H*_2X1o,RRolm1@Pe05A)X[3Asq<ig!'gbhLPd`1t_,eA^O9R] jl+a=jlE$g+k<"$lm]FUTi`RPZ?3BUU8A.F0lelo#drgnH2oJ -dd6*>n$r0RHNDAfC`JoA!e*.E]NQWh.O8CAM_Yk%s0aaP22;=30;9p`,liM"tl\@(q9K\<%V!ifKFoh0>QWs)RDAA=Ra\o]GE"3"T[2iC$PL_ M, TFR<0G%iR[j=4EJLZ:iHnSsAGCQF;-gd"'f^PI3s!WP[gbp\p2K</_:$sbN!V=r2ks&;J&Fe$:OSY`Pal2-K71mpkr.)+>g],fl(NBF,k;l[bE'27W%cKWL(J,8RH^PLqi5d[&W%Y5iU.IH5\6PfP"-2htG-L#W8b^"J%'XB6nV:Yk7'bE`sp[^i"l@kZ@\*T<pgMMK OEP@0;5<_>0jnA4(]_pf=R^SYRG+EFQe[V&i<c:NK1.6ACM)NUd]&GR`<#1()LtS_+1@kOK:GD3-9+77di^Y'>W3OMp!VRghd)Je+^<VM5=f^)qNs3.KDRBCM#6gJL?:(e1@M\U.&R2AJtbdNO&9 [\-T"p$<H)bdbVUPIIogC<lJ 8?'<oI6oigI'jY=PLB)`CVY /K2rJ&Y`CGd]`jT<qF!%''lW;<DYTq,Rl0Nf!jX]GK4r5S-9?b]TZQ?/Vh45G%)CE4Z"b*@ktUl[tUL%4;`;)KI/G(h/:GW"GjG.2Nsr79_+j_(#f)l7kaO+sO]j^jM>+PLQ$Bco QOiA;o;N'HA`eAV+654S[o4[>]AjcN/g'VJHS9Ltn7b7*k<h[<o<>F5\\`rkP@ChHLh"]W8!;V8C)&^%qLE?Mq88IHbJ-eA$;+qOaB@4kCGY;O=d8\.oRU%s[]O?\D\0JO98 L`imB\!#rHo0]i+02k9"4#)5:% A&9Q:,;sDZk0[o(GVlI*T-W[-G#J+-@r!,AF3NG6OhUcK-hXd(##J85GUGZp0Zi"9_Pj4^e])>UC3I8T+Hol=BE ([Y24p[<]CUcnR-,G=hO3WH`WDo]5;`=EGi3^d7aj#G.r2kEP6S];>ab[<d%0<kE7lJNQF+pboAUf[;< l/&<gFY(WgTsAh<:[8(i]^@\,B\?($"QQbQAXA-A._A4<^-d#ge4A#G#@?R%k'JS:V!Z[D=0j>3jh2X1\'!2D'sl/*+oZ8;&\"VXrI);dL<t+HS0(6 6!^=Zm+] :)3VZOi="O$Ynbc0]LR]d) kS=rgq4,mmKa-0\0l1aS!f?rm)4L_Bp4FQ^\)q;)F)jq3)XJ>A%d<WQ#&E4E@0"<Pf;*4BJ.^kfn>\(c?1; Qp]/?g?:.b8%J!N`31"B>Or&U"dHHk-+.`=27f%IT+#r:$0SfoeZ%p7[4RG!3GTUmO/JVKYm=5aC$WQ!X^@"9li>0s2qj)2G,AZ6%F&N#lHlaA (B5r5U5*TX\LJGd1!hOV`]YpD)_>[i*T,(*_oi*"b6a-am,)Y"nK:-T#Eq"-l>R9TSU310G8h?gm$[7DgXt4B2i7fB+IEWi`Hi<^lRseL7U>f@*+N_hAsH)J>f?[B$(-,E*58/44`l%/9]6c,Kj)TfCDaNAROGXnlUaN=WIt_!Y9b5@@?@57K-68'\0[`cnBG.YRD@coGCTG*&ChORm*2%a"<'0s7TKC!hp_`.A2Vi,d*)Zd Iq6QK^KSO9[n`[soc&tHMWD`s=K]1h ?BbJ?pH.n>A%CIWKNsboRXU"/p%Ma"iVi`mA V<a$IW"fdA-np8qbLV0P=UN(i]i2$cr&%&Ddb@`i:+jL.sb>'R)b^e^Ge!iqH`dqTs@a6\7EA(lWKVHW^,,2o5@moD^Q4\GN9YPjq7K4e`AadDQL-R]3/b89]MJ9jf7*2#m>=*RW&Dg1`A)dAjA`^&]^,<VUqairOTOY9@q%CA>OV.iYWHliSEStGtBgt71qQY86*KcG453U//XH5:'^R0<[=9h(IsMdA)$%L(R'mAW<m&07;O1 N6a8EqE'ZCXkqF9@DoE^UMGOkP);plN"H[aqVD0cg+J S00;(DcDDnA1VZ9;484q$C5%<ddiR+TK>5BRHkMP\5dm.:"J?0]+<SJ>b+=Eta#\XFb9VpAZU6;?1S^VLWq$\!V=./:2\+lnHEC=.oMSj/E72a7[kE1ZM$ h;m1=lfT#32?VZoCDnK?EAA*MJ<fMq-j9?f6i]dP-YM$I=jjPD,L4@GU0P &JV7^5sb=Dqjch%B<^/]`n!W9s,*1ctH.o>%MGB_l\<&/P:3%Me(rQ3N&'@,b@>KGk`4D^h)Fl$DmI>L:J>^1"MYHK.o^!_]!qj(Z[=!'3S._MeE1GdPrI#i^#jGq4"h\DZ,?i?jdXMcI\MtsT1:(PG8#?DM?Zse)Gi1OC1W:d`69"akP7!>:PcQc64aGhpcnC/A+d/nn@fQsG3D@9+i"GP?G9[f.3W!RACAqVrdn!k/VWJSfoh;f5C!H:a,M@n\7_]oT *>nDGh*r@N?2;9"6cV0-.e4](:FDEas<%>X fle&l=!C,q;6dNIU`;?C#[p9*d+'L<On \ A@egA;=o)["A"0,O0$C46I,i^LPTlqM_k-FYq/R*WBTBAt96f8:+if2VjTP#dh BimMR0sgI^+ik^71Y;h,d:EUQL?Er^O"\<(gOoi!]%`3+T^FtsK4U(\B7kps $_k_6g,VrYU%V?A@Q/&h]64f[L,l,!)YJ(;45?d/i#Xf`2Z`1-OoXjlU:2?e:L<E/*$r++T)cX=Mf*r`rl3c@i-NA6CC'HjgHaIPaqLG!)V-:;&Kca.21_[@Z4??N-4p.e!b%B3A TaB_*'27 Fh%&e g-9;"Yh:as$\*Q)@gsV2Ne9Kce'ANN--E<O`o3R<nDi\R4(<Iqp7$qVtVH+M7JHtZ9KR=YGeDh7U#[Wf27Fb9sh7Vr(GA/d;kF'A'!5t4VpN\kOc.gT$D\c-4[XIY4*jgX[HZHcAA$g\k*8%c@:=lfo;#<mCjVrLE<k&BN??K[hLrWn1$1Nl+1#*C8ZGl<bB*C@CfF<abJ^PQ5@ D H)MF;2Z\-6Fd9f*KUSpj>N_aX;a.e2PGRkcVPFIk3X*q qM`"jRY?>#E]"-`YLK[C:QTa/,8p=1J7_rZl7XX-\rlM0;$HGfZSt;_Pd/DPlGJ+E*aaO!X['htANedI)<'j+s!KKh@q #VO!HT3m\SF$Bt36o@0tc-ZYFs?VnN2)D,?Nf^['h4m#0;OLSfOA/dcHiX#L8b4dnDs-nV_btDU6gJ+[C%Q!&9kL^.Xh?JrO7jiCTc^3d@;\$,t,+JQOjjf^FUj+*m+*A4]??RgFBWlA]bs/CcX49ejPb08lN]h)>=g_C9`9sY'g+e3;A7At.1j@>4gM^Tk0S]E=;r1Q*p)8ira/O:I+9/_QiRc.\R<,PDD_lGKK4ff*<AEG9rt%s*]Bll_M[1B@DV\`VXtD% !+-2E6^M]e\URpb1>*n2A@HK=&?4IUAk2-S-[E E`Jepsj<LR3&st._hb6BfP)*QNLVW&3B,-:9kn>P*B-$@`KaMlrHo]6i-PBP]%i]$/FKR=$>-Nj9,m.RmT8H&h.Y5o,Y4)8.MPWLmnRC$A.D0pd>3C_sB(-p%7orENVmP6Q2kd*SPg?M+GB-RBH0'JU%NVt-qg%>-A-Xk'!V2sEXF*"<2[:htt#e L*[AMYK3B$ .lH-Pk85-mqpcW.2o$jlf9>%UCd%E2(O6)#kR1,1K6OPDV1[2$&)bJeFc/R@(2Vr5Ko==WmK80+s(4>Il.0SE XX= )-<g6\FfL;-8;+hA;sLS,mYNX#]=b't]\/3mj0lY&5gfCE&)F]e+SJLD$.]Zd7Fsr2qbNMJ7#)E3Ah>[W"=@BNT//C4EGCWVSGo5/iZKJ@$A2:5Z:02L1eR-1Fdh[ljahX"+-XaD&c2`=eod1g"_l_mIK,kVP!.1^7J3\YR%G0Qjr9N/]hgAdC3@bE$hb`$[A:f+Bp1rYU6TH0!KcnRN4( r9 ][nqNnS[brTD(`CEkeoLoKAZ-Bn227d-k/%$i?aU2kD`I!Cjg& 'H-/o"E'7bdaY1gL6bpAefnAqJabJZfnQ"^G@%SV)S.4 t>>rrdNp7f5?Rb@EmA6_q@(%OCd^_]SDsbgf+C488AFd%Kn@dmQ9D\8P9dW\^/+g-;_?fDr) qb#AY+T"R^]JkF-n8IP7o:;Q7W=4s&A8?IKrn0U9URPPf0Mj7^q'AL^<(D0:UsbP>HO>&N6@J1`s,&^j/Gi@^#i+YjnEf>G&!)dohal(\&Y^d\Z0_+LC$c6OFV>iPn9WCd`?eM:-Ahk[#"daffELAi^sAqbgKAf9q-+=^V#4:WJa#fI5rFrU'BM:a?b-&_-j&[T;,0KH,!:poUkAORn6L-U9VsCX9r<25r9g\hltAV79W%b'k2WC"'E6H*:EA A!V1`PnSba\kVrr'AVShRN[''U60+%2)kll<+f8+MefEDtmsXgB^;_O5A6cG5j8GpWVs#bGp(;;[oNB9tD,/D3[pcJ.@+@=n\F*l!CHa%KW@(&@0>=(W%mOj+"?og>4b;3Yl]ocT0Nr'C_o< P':8(\3.Lcs9NB8*WPk,3.[_29,Wpt `+h%:0\]?>$5s56aeiS;7;tHIgZ`5j_WONE,e`gJPR^88K+b VMQ jWI%]mc)3]1tOt5\/?;TM`=$D# d"#pfLjUn"Ns=:RX?gObQa2a[i2g&<^(jG.ZQ]>rJcqWpPjlA#EYif^<&.pAl\3=H05lr.=K'@dWb@AWZD .""MQ7dsXcE^g0t9(:TYUlHjY>DB6DgGP>'9[$](VBh&a 0t&@Uf1B9Bq4ef$]sPI'S'"=ef&b\/j<JP$9RfTA&s_o@</WN[sF=k\**29HY"(2ok6bIC0]Vcqp:ERXt7'+m:ASj/s4'EHTHV]NAcTk"4R2D3>'HAM"s1tPkh-^'GV4j"f5sAl%WCp[Y)9HJWC]@VNTf:o+'5_L5 =R[Y50##nJhCEX 4(!G#<9A?oi$pq`Pl&`lPWVAMrBDYaVam"L70VbSbACEAi-;]WP )>Rp4ep.3Ap&QF2Q[C!LI6WM4a*f)62!>29VZ6NG]7F)M'%H@Mjoq#H^+.XZtnV'Fp4H#Cp?055[?AK3LIt#_if_"9msn[+Z V##)Vq\/_>kM%I.,h=WA4[f+Ds:SVRAoHdn!o:CS;ejT"?@k-Qj*2!#eXpm>9RN&JS$Vn6kq%iOQ-g%Cof=`\A']IGVV%0O O7"qqeBtJ)Ula4Mm*86#QQ\TmkR/!J2G'?6e`)6RVq<DCIf""2bATAYWG.?PrG2ls+VR_b611R>5%*ItWq)P:5pC#X!:K^# 3 E-"eF@s5X9=$AZgJ>>YfZ.iq_C1t^JgZ.4D0]^88G[gsRo+=^/8d3e/(lr ?n4_4EL&%VX Sr$$S]@@d3SfX:\!>FphR;%P$R;TX<bL`VU3FNLfc<0osA, ri$JX-IF0(:A)PWV&sfiFpe8h RWBEeEagm+Vf^pnktf:V&nB;XarEd6A=6VqK<X#4L_3=5_+>>\$q=%mafk\@Z(C]/UZnI9R"P%@0U^_pf`opkp8.>?ZE/c&FVqlGBdYsj*S!Dq^8!K1?%mR:g:PCNqagL8hS"T(l[ ^<\J&9ZN%Q!A<P`C:*^c+RW1#c\_?*bnIY?5-%I;+aG:<Q3Nl)KB/H-YX4;;FR>tVKS;DDkbboAKT'nkBqa!Q90#LJR;..-te=aabVt@40KFBr8h/T`Zr"A-P\1`84Xq\fCl:USe'(eR>dblk.#l^YIH,*rbK4(Ws,:?Gp@d#W0_+.,2aiK5trRDn`KO(+4kemO.lJ?g^bOsWG%D^P5NP*$nf7kFG@%0W]MlP*3.$TO^l 9;i'p#OMAKdl/rKO+jU3F!JBFdg!qXAl,&sR<'o]*p7V[A\k[YNQDr@"oct>!h8eIH.QU5'6L]Vpe*-0XUhJ,5aAkK:6]UlBLMtm5--at  3PA/YT@^D9!E;%cUR(ec5*-SHVfBA]86_b$]gT@ FOG!kf!mUmpI5A\lH,^sN- \%?.W&ReT]TN*jJ;3!Z7GWRW'[\]=Sf%A\GK$6,s#'Hr_ME8DKc,HiE*H@0f*_TC(8^'qCZrbh#.`50hC]9A!oK-Ie?]f^gZD)'sC\JEmKPK]1&6U:A<A=HOlI)9?$ErSj8$\)6.14Xla@eN,lj5+Y;g@A,=V\l7$h&BI];RMK6(__^n\[Z6rLKo`oO\q-p/$q%AqSEB-X"A=:AlDR1lKCHVl.Cgn`4?5C2iS>&g)d"GQDg4PJ,1.ADoP36IMsso$*m!@4"Geh>QM@e]Xd-I"C)D=`:$5An$4sle" +\s/k".M#dG 3T/,,LipcSZYU%c_T&O_/HrO+U,IA.$a+=U GBt4BgpPB`!Fj6< &#:5M<??Qr .T[`"[Ag"O^2!9 DWIQp_/7B.t6+aA/W9DZ($JcYDAf+Ne@iLs\;P`/>C'e0o,0](Clf:Dfg@-F"`ig:*Fr%>HIQ#V/?,t5H4B<Qs^A[l%88+d<$'aMa5Cm.fD9:A=LAHbpA3^M%5=rcnMAA$pCANJ0qYil1jG,8IPA/4.,b/JX#nhUbM%Ynn6S1]*=`pO^q_dlCh7ledKj1HfCU8$"sA=<\K=qKAfEX5+*?liR$rUBh"W`p8m(**5--fCj?,18QS"?h5^iaMZZI'V_qC#JPCr.`&0Q=n8LmNemp1Z32eBO;EACRQWaIaj0(]8dalOb@!NV2!tkfsC?+)\'f783/-1Yn4lV7c*A2Al9*8:;(^JSd#W69%p$jqQKJs8L,fAaCLsOPT5=;+2Sq%VmEA<1h#6J-KpU$0A-aA: $a'NV]oQkk^(f?eAnQV&tVO&a9p)A2Vf.ata,FqU]$KsTf']49JId2t'R"j7jO^$A;?9:0HiEi<scJnpnG] #>i(OrTP'Wc_G#2W[Z^L2AieEf%=k&&-a0f..E8?2gh7=S^-JY'KkHm;ABpb1&)@lZ!eQ*!<JE'>QXs0.qnTHkkO/Vi?pGje3%^0`EVcan>G`Xi XZ>kheR`oFNGZ'#pRA4:^2)Y).tsO%g\YYK#n/sA2gO*?MZLNpFXVcY@R;S:X3;9hHgF"N_JDmYCE,=lPY+"&qkIgr@t!!d?I5bMd^Jg2 IVIA=FRRat.b16dEc7l-V\7^Om3 LQd0I,tsa@fG\sOMF%P-K56+\82XDJ445em!")a.*49s@>W6`j)>]E$[5h+b`-ji*Q! gCZ01k%VIBlCt']*a&1 MUSJ4H+AH(BYE&B$7JT/TLbqtY9%K,r)Bt>XRsk[l]^9G?4p&N2.5J)4#k''Mq(1/FnAeCZrKqWASh/Te^'+p>)O\4rL[hY)F-Y+X,,@"#J2m:a@\Wp-]VbfRRl^$tA\!)('E-KC*[K27;KbY#<ErKh#`RYX>$*l")_lb'NtU:GX%n=[BX`.$6RN5[["/$pA^,H5/*/;WF/H.D'As+N+/6.YYhfjX-a1Cq&?6I48OVR*"tDZ=#p\&cDnbnP6Qe\tN6C_Wt2f@ATsR8]9[0#s*IUI>gA^be#nKI`4fl-]%0qXQ_VM1Q=bY1hn*,3UIBIMOF 3@QLV' )F>H>lfHZs[P[B#bRK_f&d-5_d)Lj\*Z\Q+aI#U)]D9TN'&!pG=<8KScpJ'WjU?^5&-EaU$aU5AK)E5eCIO[TKt[&WPomg8`m=S5j9lUKB$`i G<H;BqtakAhJbX"TK-41AnYEj2\$ID&PhN(sk5e1)Pqmp]!G5nD4h3P<Glm!Z^^!Tji.VZ aj]=1/>K5+qcW/>$FKQ:_rTG6K,#%PWP qM4f'E^ r;<_\Ja4/2Bo%a:f>)Z`X?)]0.V-<-=fkPIe$tRoPdI1M;;d0&1W5T$^dWVn!CX&]b8@:_AbB1c_V+,_:NtkthMM6m#Lh/PR?VEqb&lrCXFC`O!6+`Ce^5Z$s83MeK2`Ho_.jo\25P7ghe3XQb.3bfF&+?#sGeBp,?"*KNh\1XUqdn>j?V*Jm87r%U+ZCAgeF>\(9SPU@GI<<,C_j$QjT<fn]FFBGFPo-WqS"a@&T3!;Nj1qjCkfIa>>J3k +9`RcbX bL!&*U5Il$PjL&^W>:$=FcVZ'qg-8VGg17-o1"B:B@iI$$'h:F$5#We1rS,^onIE?S/@%_gc2oC_ AG-MnMZ b[i ,-#BG_Z/jh0;ebCkqCQef8UO"$M1cW O<tP-WA /US8VJNV<'+/3Q#nWt>"Li;97/9?Z1bH8MaXEi;3aAC4-2dLtfU@_=>R:[Plg8NkJF<4,dXk\WOq)tSP=T^)b#G+18Emjt.eHFst,G`]Xa(GBJ=5;"/>;/=&* +'/3`Ag kI-[i*Z/T2#ZK'>7PaVO,kW[20(nU+(BqGB@AaZ<4:YdG6jUAXB0CVteK!7Tn0Ai&rq_J4>O>siC:?#FqO6n,NY\_;SElXKtLD7WQ+*/J_Q19*]D"H(nP4,IA)p(M\X`or6MdT?RU5d-Mg8ZU)FIn4Jn4A-AF[mQ`f.a`;j[AgZL>3$<:jcnWk/!+Jajgf<F!&Ap:Hl \PE$KX,Jd,bnNr<$>:;p3reF6!Y!$f`&68$COR&#9<["a*O2dkf]hWRNjKkl2K/Ts+m=@TjE2%^/R8ST4?+*cSY`M-+`dNhd+Yn3d9GV_lTP/3#^LKM!h-j#0A-QJ98d8(DL]Zjm?',U=+O5e_$8E)ikIY\Fbc[PLVco8:NYq/dIE`bYm)0@7Y+[DtHrlTd[B?.TYG02neN7s=fF#HrcdSe#B'R\a(X%hKTUN>-Gl]VnX-i)cVVI4'TRSP-X3Y<7,K[KAqoOIWbhWD18$\*^h P]LL4s7*KdbJcX5HSOLjEJ:DY&SA,nZ]\\b&^r41nPIoQ(83k<:K^]oW940AVfHYIb`GW2,C.G9X*tPI;G+RrZ^c65Ar0lp3Ah8Pc2CAgZr=9DBe8X8JmT;7*%Hkb9tWg;Za)Lj(VUX.>9/XbC>GrRHqtJMLA,,Sc7X:<,SPAVF]iC?=7CX3(;Vq es8I8Yjb[(mkYc%"+j!hTkP_c+_K9"KLjHo_2)$^;:;G;B@`!$Q6(W0G Ajb%tsAI'YWIFM;gE2;05=$db5GT#s4i9)bp//Q*GT?EknHAdeND;ABONA]*fV&3'-.@ae oWH0dCS[?5DK!gqA-<H:Y\-sC^D0@'p/J1".ZBB@*(e=/@]1BN"8V:FmRc[pWIb$*]R9\:GYip?cI\]jofDFVk7PI+3DniX.[?m<Srr"[F/00.cCMM2GkTq AA<.FT5I.m<BT\s"I?0eA_G:9,$QsXDANFVD(0r/7!pgpp.qgqe83ZmnT74/%A@b'RWDD0hB]jo"8B&iH!Y\8R.'-AB`d4p-r3k$MoL)XHgsW/SA$0Wp?-fRfc[Lg"Z[Ql_XXdd757DXnED><cSga-r`sHH))obA3YIcNFIKq:<>b)I7!6-&ND<'@i ``I/YqMqY-6d$QCGOR-IiDk93Mbrcrl4K9/mK*5MP>AQZ/m6_EEti,m"A3X [fY0f"(g'ZQgE+@-OBg]=U CN"=?1m5\=&h0C2G3t-a.Zs5i-PaF<qZ?g?C.BjVX tVUNXj;q6;.&'M?hVCfN-G?462IPJtK2DIM4Q6YJ<I(LG8!q8#cM&c]YP9D! 2TSA:ABUnM3[A>1;QnAAZHeio-9sq9\UJ6Gj =W^(rnNgok]mS>Fl3Nb##)6#&DVWKP=+U3C<YC3@p <Kt:N@q@KJhWGdM,acAF0<,nGNAY1jm=XGaDBMcB$RM9E5'd5Z&;KKADHAW*#a.MQ>WfV ;?<?<+cZSpd-+3V6o"!j]p53_b3KQUP0G;72`'5_ipWF59>/k\S*EjnOe,Ep=WhR9ABBiWS-%?F.6NQq>n#6k<*H`8U^B88+:-<(^=T,5qAp.OW%i5ncXA'[#2@72_tArB3s?'6=^faQ[ak/XQ*bqmJQ`C6SLM'E8i^Cl`bp!c^f,_5=t)o;\G*0(U/"m:)1qC+JUdt02caN)oS(WtK$=pB/A%qC6:Y`Y4E[UK5KTG47mePiqFRacGX9,ps\M1sK%@r@S,9fV((ond[)ZL8@.PR_o+2U"J[IADF 3!5sF9>UJIpQn830RX2VfpQ@Nomt_h]R0#pa?lXDjhQ/ZqWjnC2T-5bNF 0E'L#-.t+bNE!:U_W/4Vr?Up<\Kj&/K.p@Zh%PAtdXJNA@F Yp4D55m\p]-[/G2PUo5>haQq/^^Yhl*Tn?Fad=jp,=Xrd_eN&0?8G`n%8X_Eq98n8O$hY=\M,[@n$b32JEBA(9=-AcX'H3BX3\Xs0U'9m\E<a" N>Vs[(4)&$9AkXc:(]HX.dL"Kq_mb^2O"nJ_A/EbFNXT9"pqsZ!FCDZ5sg%jm2fIf2A:_A23WTjS^?P5ei0iq)a/#:jV8C7-r;SP>M\c_coqI`W3ripm6No[M0W+jtcAZsPS+)BdFVh>#lZ7De 'ora7XVAS@c<ZCB2gnd$%''3h05S/#%$'9V_Jm/Y46X^e:boLHs+2kIeF_(s#Q'<DcSm+_reds>AC?CCs35JjCXb9'!AJ-D#2U;MO](q] ?jhTskl#V9O-gZL6!ad&b95Qs-UG5hNWd%a%C5B;Sq;;"A'P^0mJ]F`SfkP2aQ_-@BpC@TBV#DdfO7asSY<qk)1\FHJaZ%A##mkbL(CR AC.0Q!QcHL]E<c\'XY4.94r_YQg`TXt%\[sR+GAAgHF69[2<lW08PrW=g=[b>'!De! ]IT$lSo-c;qS"Vle^I:k(Oc+Y4DD jQrFXATEUlm-3&3Za]Fg<05T&^!YLcL%<))1A&>1N.YT/D+):#!go-,+31P"MC;k0Y'p.<;CoJGo+a@4("!pX=?Y"$0E1Y"%UAZo2_]&KiNjH@*PKmTY@7I$_a)$1cP;OVU>I/$tG3RJ02Hq`X^c\_E<!_i2Agjqr\9?K.O$Jj!_W8A+cgJ$Ln2rB)8J%(Bs@A@iQksIQD<GH,tJ/=ekf]!mOtoW. >MCX8Z4#q,'HF/B&KiY"IQ&p+$@:i )1)3/D"*m=2MHX\CX;mQ+]((C]`%$A*c.L+3<kJE.,V&l<9hT#c,8ArOqM"&6GG3o%?PoJFSA, XdL >7:A!@A\66Fih9VRW5dQD?1'"t;fq3.lrYB@R>7Mc>mpp>g_DZ$Y P@VE)Kr.WAjScRpf:d+af_S39#79BfE00ct?DraP:=\l3hNQ9H9>3_Aq!lD^-ta3GZ\W;Aa7l&s`q1?"F\JOpAR&XW!QR\(AB[ X(t34Rf;1X6_%d4-20)=!4!TO8I.&#nl/#.P\CAYeHJr'c$b5EJio^a:e%m4tqZ$3H?%5r)E$$5q98rtU2-QbqXsLmFA`q7AjqOIK&X19N#beR,]q1>^?(Y*8rMhthFT1qsjsTCGFJ6BPpJCVZlWC>hpKt ljt#+1DDZGV@eci,19LnK]j1sA!g>f9G>&rDQVA7m#Y8a6;1q8f:3Gk(VAc8gKXh"f.YXb0(H4mc%#?sCOh#jX!/Qa^c]5@*NsC0.;WIMJ2l W/h2FWr'Vq),Jqd:Zi$:!eDaC'k;qG$1>?Fiq_hSJd."BEJFU!QIQ4TMd%A"5rD-*WAmR_BF;866s-s&Ns'D)fQKWrp%9Vq27(fZrjKA;3"NWDl_]WD+_Ji?lY"D%LRZD*7m+:(0UqS`3WA:;AG=rKUii]qJH[$+Cm2c;?te5#YeIjm@V@(E$U0XQ^-Tq/*V*@hniBiK$M&"3T1]hV3""q@-^7d+D! Ai5D;=k_t]Coa&&4UesRq(3!S5XQB"j`0B`VIhBt&O9q+YUUn1f'1GdoKk"H$&[A:bst\+V%FX1,,]m>k%b!ZY!]mk6Aq0aKQfmbA?`-"@&_si2ig^KnJA2i4)5RR.m[1C?IlAj6X cQl5)OGp`SE>4&=%)ofQ;O9.0r=.pcm)HY*AMC86%"g`2_Ac2n\?AbA^p<c8MX*#*d[SL5N9XSpP]O)JFk,1@P[d3EV44.@RF*^Z;8c3KFKg`iYA-G_K^a*PcbN`GT4O8"n46?A51lACJRdmbsNY4Pae1tV5+3L^ZH!,*4<9Dre!AhUb)T:f/aT_'hI9!S7ZE(->]!,HKj>g5scI[8cL<f/$?!+5iQVL'_^D6WMXg6fE\ImXTjY2pN.aH-Q0A=/SNO'$F6%#B/;AgcWY%cP?14a`l=2BoFZk<`2<q'+$Pq=OfF?s'e'<*@C$g7rm/0PjrW4<e6N;..#W\X*@s>R# 9snT;^9-*N3BG"rq q#R;K<`"eb+`<"ie:@sA:89MVQ8N4>2 9\UKt':KMRV7!>j*Hs++aWcJOOSg5'QcFV%E7"_I`k^G:Rj"rH.42PQ1fF00L`f#pJsroLXFr._M2]-J] ]gPaAi#BA7M8iB1e5P-FSl4j!GTk'*U3PnPZ)lQrQ\Z:EUS:9i3G87PB. GMM?=jr]=D4BWeWWtd.Zp$1AbeSIAr-+-GJDZr)g: k4EOKl8g?EMYqAmK0U&N7ogmHC!A,]kGG<>!qThP`+3n7Htdn9$#*WKPDe"Z@7?MH$6AiiS[RMsq+$2f-3:U7N"X"(<OHg':MM <BWW%-pZA6 pn^8?Ao?Z`OO`/XM/f1OJ#VRP0Ke[>1I?\="i]1(-JmY%Z/4%)^AMdk/n%=`%Nom@Nd13#(YD`(k0FJrFiI:a.F4#N]U2WcD@rkT!G:^k3t4DC'Rm8C]L`ND$q]WYe[5$m[4H(%CBe7.;,t+ArTW!=lTKmjn!i=_4#BdX(ds1#1Gok3GC;DcO5WF:7@BT7[Cqgo> B04p'1LQYEYR50PSsAE@1hi(*fjocJ@L),e>[3AC:_ )0G))l6p?05M\n178XlA#h^lpG)>\]DS^_D&mULnqgJJ:2^$AVa_lIFh^dkAPo[gt?C'B+H>,1`_gboi-M* 5 30GeG$5B*s:l:O(ZBeUt!.o#'^86\%Vjdb!0tQj5Y,IJ"(qUD(Apj-s3[2I]fM41Wj/#c@?HrT+J=/WlpU\>GUj]so=jIqEV5BA13AD"d#8hl[#^2siAb'[&!F_(fRH&%h@NAm3,>XE4&O4>f6IP\6%nTrb De@EYF,/Wbs<dB-r=](81:nZT6%EFam7fP pQ<\U]-neKhi2HQntoU_IHXWbAZD0EI%&`i4Yg,C'd67Oke%iooo[b1,Li30efA6r6sR9GM*r#06@81lGe(&+ R]@Mes05A?]SL2W9o_QDO,.nBjHri+(CC?ILngU?%t"/RdCUZ2<1RroLqSKk4E)+&1IXeCTl]H%mhW#EI5)c+Wc.GHI]cHh8Kkt5!mUpV9$to'0&m95/c>3%@p@E$YHQE&Y`Y_D)g2@'/$4]p/Q#N)$XnatM:<:HrPg6&F7doN,Nen+bHtE4lJN&QT9fl^<G5&h47X';`9=/<)(\s,-p,3tjf(=37aR<n#R+!*(e>P>W3j&Y&Q!kra_M9[192YW>R`!U^!AS^62KE;=[AVrPK:i^_9] A)mU%SMngF]GZ D-Y+5S@HbHp'X^@*/V@QcU*>iA1dgK e<""`R^YY^):rZ!#9#=ApYQo.EkJ4.*EXcjqmS*:kQD6gYdi$.HBnsCni^5rq+SY\0hC=:t:UH,Ns9+V&k,Wt$DpSF!3HfAM^fI+-A*"9!=G^+hL9R@4XRG3S21VGfZ5a  c!(:r+c7iel3<l.?HpmOQnKSC*]5j4H2g$%qk>(ZAIbQR>L1BsVnn3L :/Blg))[-&h`&IR6YGFCXBKV&G0)@AGTW7QY'$XC0/U<(W&*<nT9P_1/bWVDS)q@^?p\T&rQ:.WW-2VB'ms2(0L(dYMXM7N*nt?^EXqdZi;Wne9_t2`&Un&_'N)%n]\`Y6?PM^]GjL.^+1q&?+Dcq>1R'&Ynk*A8Gnl]3j20ReM1';6T_BK*9h@bB k83;"nq%n]FqqBQp'?QD4>6oSb[4dm.:+@YRTFMABYW3eI.@<D@,'o##hVAP?B*kMl@cY+AshCHMM4UClWn#O4tpgtU1a*"<OgO\Ora^o2oU`0k38E\V,Rf 8b&lg,TA%>5 cJ_Zt8E9640;C9AkBabe.0nZ%VYBYF8;kl`9^^`aF7Hg''q#]bcXKV#_@pj:)Pla@+ +!6A*no]^?$V8($RlJc]jXWj6]=9M61r*f;btbBT*(N5Fl<[ON+'4#X'hsGeGWpML5&6XAIGWjsRs]B]8'IU#-m$7i-RQ2HA)Mq<dd>NU?/b_KnsYSD7=8>[d.)*SQs^K/"+n1Qe2B`R/+oK/3Yb@C.1O,>kG9d%=D8A2'aG6Ln-P7nrtoBE_;t$aA#OSj/#dJc=[X9D#^-#i1:\rjR3A*5aZC"2"bQ$otgkEkES\MoU%*H'/i;T:`f(n8:\;"NGRgBQA<.Z@,7a3R=;gZA9MAV6!KOH:=tKWJn)fdoSC=ttJ*N,B5E'_L1?Wdl-M]bGpf@J6'[gRU,Y#edf=T[($O:22\<QSt[,8TOA6Hk4qB>4Mo(Zn1E85:6lg4+"%K3`PtR9*R$tlCJ7FJ,bcbd^T_N/nA!7*QO\0t7JPSrlf:-Tn=q`S7WXG1;7d!N7a5<_6Ul`M_eTE0eZbfb0%E2])7@P3hIDkf\S>#i$Z*[p5>s@ZV9\q=n_O/Y)G;*^S>?/NXM"t$M@t'am*M92] \VEX]^G_XTfDKL4\tA\Ls)J;%:1E%A@8d>&[Am,:Ke\'8kZ$=(+K[s<STch@rHkqO7h.PE[s!nf_Yp% s$7RK4Jan:"Gr3f?nSAD%^LXS7]RIO;VA%o8KAftsO4HE(/nZcZ69k#n`F49Oap(K/C=tP<9o%./Y=S?ENV9N"?Uk50BNnNUA_=]FHA4&-n34/o,B]%G6s$h[0X$ f-/1N[@=P.#PiQ5hb"* T(\LZ\R*+9.3OEi,E$M7_s.#h$UjV)Z[?PPHT4Cs^>)R]rj2X'!ID"#VO.>Zh?L"0o-=pY^!=BRMA5g#ZK8-/:ab3:mo/F6tL-jb-N)At;%VA["R. _o/Wb#;5C_(NbF1F"G<a4IINL+I3p>4N(oh`^$18bA8aL`8[>38W#c6t/dcEkQUoZ0+S;LS;G]a\>"QKCsKT4pG6dTVg@kPTZ6F$&*/p[c+n,XeFd6YiaE 'a'n;C@t".Bt*Z?Tb8A`2sErW0CXD:rQ&B?]Ys)+`St-2ikC#D<I!;ah@a=t7E H/^pR!=D4%K&l;nZ_+`g)s%?K;C+^NTL6@F(5Kb)=B(>D5$!LORR*jHj^^eWiQV9GF*EYnr.:RT<+^oe^,DR XQbpF\JalQlP2%"%Q9U(?XX&ER:`cSLl9-%78O7Ol3BJ")P![X?J?))$2T+395?;<kl$ponP-U+QoLVARdA$?eQ7T)l 5(-A$p(V7BE\3Od/+&U0<N8[3FZmH)E]:N3L]Yh/h]maKhD@7=-C!f1%rY"An@X"V(='5_:7M/\sD,+saTiZ?Z's`+Xf[MkM'eQ\A^,RJOh??:.g+m3lj1*Cj'U3\@X=o,mN)]8m_Bj&75@&ZeRtR?DoV2;Vh($W9'_Gg1h_Q)(/=<p_2rJ&C)^g,oq(20sh.-`i_MZm-Wt` p0$P*'9Ti%l#oNnI\YrtB$?/3.ke#Fht-$m;`phQcSNMAAj+h\fYbMF]*AWAMl.A?),A`,+nk'6^]+P9,d>[A5/<4kqm<(tKhPGf*D.O2$-J4t2p%5OFiQ8Y^1#b,5gNYWsb"e/t[`JqnF(*D+5aD2!_"bGEcQe1V+>BARj*J:t*MR3.\WiSNg8BP53,knAVNm3:pD)pAh.JmTnC$A1pZ_$9VOs^[n26PgFb5g2 WWr1^#5TJ)F,2=R%KSp2J!)?Q_b$s9/?lNTAr4kb:/Zq'/%o%K>Kt1$=L5Nroj9_[3;.;+ld=j/a0kq.LE!Nfn?[E<UZ?3f)(1DA/>N!1@:GsOElhN0=qVR=ik0I<"r/m^ZVk]3.Ee_3;aACWCV<;0thiq]hCj\^3/eC*<Bj:\.*EAXs^C&V26/WA"b(`m!Q!^fJb`Y[sT_;EY6VJjN0jFR^?KGXWYE&.PNiAo(l4Yj3Cp6QbAl &S1frIP3lPta1'^bM$t_j$H(c3br&C)>8Y^$RKh7^lBMQR4<C^MQ5RdO`djRIcbnccbY7a4IU@2%3!M9[6CtHIQV?&c2fZNkCnF0=dlqQ.l8i(c0p.1J?q>0A/7P8Ap>4P).gUKPe2XD,f7pAV:<goLf[JFeEED/H,<Zs%VRV,O..7=<SS[/1gZE*3 U=t"1KNt'%W7]n12+C_Eb*2"]'oOiU3q::&AUbZA[B#>aL^d,Un`am8iJ"+o;p7<(VIN"&q#g's^eQ1lj<G?q597IW]g4! F=<7I5A[,H@5GlLT"4dslHt[^Bl=0fT\3sY Bs",^K.Tdcj1H#Mfb\@cb33pkjI<'\dAk(se592g-ja-6Qj^(PgBUL"iSGhm/-rs1eaG2meF%8i7K0besQKi_?L@54>k&LhTHR!F<92ZQDZg0"GKS&9^eE]$7-fad<V.48j)\=Vn[pl66',-7VMi2!_ "!3ED)fsrd_KD-RebP^>7aLC=2]h.4IT'`XR(_s&#NEptr_h5^>5[2Ff@O[gNZ?\Pe5k/AO?MlfOmHL&jk`ei$r9hArAXg."tEV1+1F^e6WeTS`MjTM4;/SpUt,0&O+V'41Mr%%<nX+!H!Dr=<GB12^olgI4BdbG-lj5#+;qV!TA(7dnFO@?#fd',Dmc9g_U: UcKOXfsJfU[_Mq I\W&,1j'GSsJADDAeSAAn&-ct&YE_Fh'GFl4tl#SE)#qf"#\dW<o/6s`XWfl;0*0j[?T7'rdhGh>ZI^t#gk]<]Q[Epr$VD^00[rP5lA'OdjbU;R1FO&*#)e _"N/8KCEOi)QAWFl<fl EAiOc7]:JKSgSACs5aZY48\Qn)BIT#^^W4E:ls#%X4bT<_`<Zt+p]%aTf?(k,MdoMaKH!rV0"/e5=_]rAMhC)fL&VkPNc8Me`;Mh@,(;.Gc(?P9$LqWrWq0@n8IY/$A]mVG#;\)Aq';\?8-@W*i-D_U)*<Pr!IWri;2J%k&UAL"k1qQ< F!NbLt?PE4/.k@A'$qV7nrh:;+G3b6T>;47_k<[$PA0RR c)HAB52JL<.+TLp,!2sJ;,UGVk&L#ii!4V\mibWR3Kr6hp5;e0<h^W36s,-UmJ)#a5pGJ&*dSNkNW]h(7E]2btEqDX,Qc@9Q*9,d)c#kIZO!X-hH[>>]d.X<d2C'GkH'$?7X+K7)SHl=^],S?dbX@PA)SFVoI'jG8sM@O^\@c;F6\3Bht)lm&s#A]9'6$tjXNNWM-9a,2.p)O4Q65;2ddWA]?V'D\"4qgnmA9-4\-fQOI8g -<.]QL7kiAtUf GBU2K)jG!e3Pb3G-m1hFt%![VD:K]g:WU#qAWAD93O/6H[&8i'gt/sRIrq6%aCBTc!:WK;bm>HrKMg2*#IWT@6#f$JR>W6U#BnqeJC.iTePg9A?T<B(&T]916Aotfn/B$XBV3_D:a-KMhL#(BGq4&r^ZDnh2EtNcH>E>cfs1Ip_N#L$s`X9aJN\Y^,2CTllW%8#r@MdsB^@7&MEfCMpFW0Ze#2!:S0Xm< +S]6lCPk9L%AFM$<.l:V5hF+eXAt]i>%)C8:VA&QY]q]Wg[;@G21#mO*5"3ACRjDO24Iq6pf8e,L_JWU )8_'+&O[Li'IJ#<&(IUnHnhP=7q)kf`2lX4m;fFq0!>)p9k+]a2 c*:'^,>BWlUD^W-63A_O&[X]Zkp\da)r !WRk#[j2H)N^4Ss>k3lVpgiLM&iSe\L4Tt"oO>s=Np)UqfAY/>LPQ[r0L=?5lMWFS03H,XM2J, VN,%O5&2@msR\m<(%sDJDPAT,`BL%sk@a9.sq7*]A;n5iHY^?&ail;J?0**s.^'C].*sAKEn4[D\Qg.gSg>jXFfX!%6AhFBt@mM<^8jOr#Ni6#U:icok"'d!r>k(=E*5sQkX?^<^-4R)X:!a%RCGU83k"P*:eNCCBfLjtA],k&+;oKc D+`slC\c.m8?LVsKJ*2Jc@%FC9Ql1*o%>!2hFqnKD0cUh/Ap(_4a!AYA(gf6?;L0"H0R#AM(Lr6%q@A#qfDo8CaZppKbk:H,UJepP'L" V2pLY@eNG`;m!OQIE!^?RABSLA_pb.FbkNoA%m_'F+;^&AfA@m]<*J?*!$NPKr-=Ze%kRU\gkn^gDsB0_?mk`QFsHcpJt3n;A`.0.5)5Y8NttXQ;]LW G7 b_3,XhdYA0Ak1Go[1j0K!-rC7X+1o;;U<UF+c]GFkWifp/XqsRTQI5PeL_1`b2]?(gs4b2PIBj8H$Yf?mq1fBcB3W8^#d90a2jCkkW&].9Dpt*)&3`=L_`i0UsGc8JEBe[HKqWJ?da9A)*hm%Mg!ajr[tm_V\/PK"A)4?>*9iOWE,C*tkLVZ^U-olaeOWM?hkQ2mFLlOfV5Zqt16o&,C;<p\4sI.a3-1n%"O%;]?@&&Kkb'do] r,Who/hQU<`Jt ^N0?d)pHl2h+,,m3o7\4k/3]4f78Y(=N"JRm0V1U``6Y&rBfgfp?'FG!bIFZ"_GefA#O.b>(LlZbfmbX N0q/c[@WlhTsEsWG&2CO=@@EFWdL0sAsk99o## L;[f4-*IE>7;%X+:A@F(=-U6o>nQ<#./LV7FPb1q!6aROsa[[\@I_F:/<2(7^TAL&8@Zo0ZcR.YO<+'cniABAE'>O:"iq<j/-P-VV8+7JALk;f<Qj:r9cA<"8IC?X"hrkV75ca$;EaA<_?`LFUiT(U2U)'iFY.2F2<'^;rcU'^[1MjdIs8pKcW\fo!<=8rj538'K.6"UAsU)IZHEs/G19N&;U!(ir@,0BK`O3@7\h !X%])j;R!h_A(NhhZQ4g%<"L=8A?6A'_Z!I= WDY4;>>^=5NB-'3375YdeL hRCPe7UQXLT*bcA[13a"@.TWjViKS^rVT.L.`-o iS$!Mq?+K,Q1Y %%94)m#8g*i QMdVkn5X*1=`$&8jNs?/isc=b,*SAmYT/^MWA]"@SM(*Je7G;7QtkMfCo416#Pl:.*NkfSc]T5J;)!ff0m&q]`7,nC`<t,>bMbpUn\)o7=LTfP-c%mTPhm:?*![U*"5((V?8,FC"$3JL]7n`.>D$AjCl?Y/E%%C,+<A[/;.9XpXCUb5G=n@Y(BjcjpQXUO^XYMqKb\#W-C$I]#n>s7\Ee&Ch]^ m-tmoYADoQX6Vj>df&lXVCc?cSBbdCXEVaI-2;72PVG b$RB*iBT]\O!)tOH&fTbp&LMY bAB$3,m$SO;@Y>&>"SqE=%gLQKq@9A<%'_f6r-9V]`eC,9`!"6cEn:@e*W%tI Oh?Y[j9Hj#"t@.#K5tC<rGR=lk;8)rk]BpIS(8MCRU1c<=oq%&ra-'kPVc(PdFK5,ES"@(_I*)8\"M7q^EeWflUAVCDN\M'MJsTZi+kXPX)43T$.aW)-s<:#o8*Hq0MD1=8B23Sj:>J]<f"bYDo]":.r;'L/[WUbel>qVVVN #A0/A#CMrgb2'slW>-"Wr4Dog[$-j]eo"P=Q-cEVCE.4_/'QR8rT+8=8T2h,A@'N/\NL8[.2K0T\;OS A?(AS&o2:S_TK+b`G:bm:e$N)[G=# ,@;\KF:R$&`D];41=E9aA)c b[Ks+K9l,3r>lZ%LBs`(AciUpF;A*$"^Nt-i,F6d22+Qmrk9@s 37'LPk3-dHad;Efkq$nJnleeLA$YIASX_A2)bq15M'1l@W@=7Y&`bqfWO,.6p/pj2^8/=C._bId'"Td*Slpmo9JY\@Fj7L"(YN!jAON2CAtF`:rDtL9b3JQ7\ZmWZ1LnD9bi,liT0(e HY);_0Re%r1=X(>fl\9`[Pb_.O)3TeSDF`+h@nQfA#3SZa@__C#65Gc]$6J2R(sB<T(r=cUZVSQ'1&W_r;I:-G8Ero67>FAj)A+VL/"LGY5Par[F^bo!m=sbTY-&aa^;LeRCD=*JNrF0H[p0U1*U@TL=2]O.?iK6,$T<`@/;Gme^Wd$\<S:W0S=//-Q@mim^i:JJ[7X$ '6Q5=jnGC/53rr[[mTgo<^:;Q)%PTYcli lDS_&F&"GRFhV?B<:&/\T5>nN_/b8Ra]pZFeq#g,t?D-V]M5$II3(^b.17rU:(%_I!:.j3M1oooLBP2SW#(V 3I$9CVNU4mdl1JpP&oq>,`mJJiIf5e@\H8i@IcP@8hk3]O,\;43*k4?'q=12)$A6>0DB:7B_el#XZ!U.5C ;/?r:qM]QbO3I&gA%#.RncpfG@UGTU#M) /SH+"r;Z(mJ+M?i]*CcU#dkn"J<4510Z.$YcW=Gs#0N:7"?0X9(C$7,ZITf$-1<(YV)i/8it@m;42Hs1b1JZnMC[t!4YHU] @*!q^3l;bhQ<F&4^(,TTgn]IP:Oo9.=?>sQGolboCh0L3oO\a%,eHENt Qc&R24M$j0Q;C?b^=I5=A.ZA>_j^GY]Ds/D"E(jRf@p%dkE13&O8AY;^Or,!?IYUH%F5k<BGsdi8df)7&IeBj@Dl+:`fgYdo(4A_A184r9q8M3&$Pf/S6RiOK<ThnJ<KN[CT@MLDJsJHN`D(+P1lMaDc=igP)Q"^dESaAE9I9>_oCpY#A"FUWrD*R9Gb8iJ<p0:p27%XHpYNSL7b#?KfJW5 $STpEPQ_9N!_P!3GT#l!rlA2o$D/U V;H3sQQAb&0c4\A902=W8ZYX*_a3hqL-5PiKYPp-)R^`2I!'\]_jgBKF!PeprB]:,EAd>Oi'HAKZ/2:RYhToX!qIIp+`N\Y2K@ e,_3i;9f.LMmEO.Pg\6b$tjF5[sQkd,3XHK&HqVJJZ'tUcnK\gikacet-hQlH&pPAD5TM[ehBh;)LL1[#-O.e@-*DWq?7aeI2;LG%UF;_QL*osn[`TKs^EqZ8oaE'#:p23P7h>HBHd`#R;9&tS(& qKeFHh<$4'tG!TdG[L*-';>+RKU J$aNR2O=E3I'B__9B_\BFolMh"6O\4rPq$f[mXa5'3Tj4I!5t!D1L4dF'rbiUdtFj!(*fhh`L27$# PA-YsF*:&o+7%AoK!"T^<,Jrp"WIr8BAB\mEBeg,&GUT"$k!0(Etj:T=J8W%G"1YGqYD9]P&nkg2-887t@d^XhEJGPa3RAeiAi9,Pqobp+Xi<0)h)BgrOI&YW=R(J^;;_HiX_f]aY_=8@ZQ4-&AKh<q!1-tspf-U6At:!pAGO"_$b_c3coN49QQ0+ZA.lcM\PqW!$GY-/XB9a$S<P&FXjFFdOY!d)10".lDKA1[\,5rP)h!Am?f^9iTiKBZmA`2kEUVrPFdK@]DspH-X7?0P#%RrH6O+E57JR:-t7iN!A?'7'L7ZelsZ=QA^WGa&&kC/;D9U,"9fGW1kf5@,FW:[b*QiZotGbY5(92X-mp7<+;ES&(::;M]$q4D4q=gWH"`80(f;MVO%hi/p%kl1< MM)BmWa0-BKtVt2\&Ec'KNqd5BnhZQ1Va,5Kn3Wneb79Hl^fd5/4)k?&7I\ods`$"A6d]cK-(,mo/<)5Ljii&jOH,AUKI0GHfkTp"Y`.?th.`eCEA<,@RLmsD1!I!oApIl?+W,G87jU\\qN:;Q,T"e&An;mI@Gt!4hMEEF&N1rIQh.<MKb!3r\CtGT,4J)E`P&gp8;#abj,gCc$H@2]j3=H5W!/li:UZ/7B\IeIH^9a^J*9tM@rgce,HO7%>*RjZB`rL"'rMnZf';Lr+M/E='=$VCmB)O@o6T/I\!Ut]RVCEM>o99`ZHXp]81FIsqa_9ab:+Z5-MK2ob:"c16C [p.IfG",\GPUBAA1JROjW.c,UpK,Dn`'@co6AQfr*G?TN6kgCX^dI]>Tb/H!IUWA`nU@Neb05D0$HQS_I`'Y4!dTl-&:p,+CX^MMj\W@1TC05 icp/=Ce*YVqS+ZHb)Xr*U[2(oN.=CVI[H"!;diAT_Fi!M)L&G1p_lR0NFYj.aB@@_X`sB YX*J9.9'r-`6C%ijb `F]Z6nAL1X/nUas1A%b<C]75JGGe,q",DDncIIX/AM2=,rC6YCZ>M@Ah3Bj]d@ ;"8DcC%orqsAT7)h9\QA=i4A+Ka)6sG,SY6X6qh)h$&*kLL^#&;ei!;()!dVO;>19A\iZajHd;Ihk)I?$orOYU:scq3Tr@<+&$E53g#k@;5WISMGOicsOOq_6n1D_Op4F:7l#&EhbpQO(r6r8aJlJL' d**Nrr/\bfhpI`Q_>q/-3M)!8b<seDU $<4 []6";L]3Og $D5SeY[d/Fam*c1e9g]qA:Yd<>+ZZSF[Y?: d6ri::(sr%,.L,8L;9O'A5cq`KI!$9b0O7A"\:Nc@3LYA"eK3UgBJ/$\j%OI_/D9<;2m.DUr`q4#eleY"&UL!AI:=8'g__)"r#:VN3D1#<CbE+^0Zb%8LF>Y82mEA+Ubb-\g,AaIN&>?POXk#(94`fIfA%eQG!(A(;Z2`mFGs]c\qmY:nXY6#k5"<7bO]>5A?(m?^3PQ^C<>Yd;WUFRs8@D\C9l+ GS9RC/+R2VWe!Q3*X5=_sj!3PDC=A-?"SM_`CG#^.j-E'R:7:MVMW(TL>lO?l=M*4rgI>:052*0b%m[dOD"f AI.3n.MjLTn8K:aDTH@mTqP'qQ.HaB=?6L?b!ma5:"A=3tY5C)VRF'GIdIEa3JCfKWnQQB&^e7BUcZ>Q7?WIP.2dP)Q#T^gd0&AS-<EX<:^Q?j0(W2#REkN2PO^hGcsBpR4jkrnC0,r6(XTZ b>0L<&@4\LB6pcW "VsjB@0LPLMr 7qm]ga1--#P3;Wf4FVM;l]I)[Vk_^:IiW+KG>(,SZr8_%Apa0>SUBh<AOT:YAio-E:q1Qr70gp%.i<*i=k poXAGj8qNT>AW>VY^3\JA\$$3;<KZ$4.saZo8V[QCi=rn.`hE?$?5]lO$h+`0]tBa,dW40!'s-!U+<A1"VH`UJ'_7A=$9*$QNo3.im_qr[5e[W3A62TIJZF%6>RfIph*9P\MbY9llP22N1%o^Y3oU2D#k)*W DCN&1$Y"@TSp+`4c7 ]t0mh(IG"/AXZ,D?i?_-%l.I#g(^#Z3%g'RmB4Us-T`G]:Xo'rE5ZDGl5@</<6WW$M%$DTW>,]3crC8_:^HQF6h>'d&!%3['k9O&gFO)r7SEe=_]=6Oe;DaK:XZ%VNm$o%'>;M>q5qH8@DFFXFU^t@O8DQP-J*'"Fj+N4Ur5[?7h6).#+C[:J6I39>Di2CF+] Po"7*"Ih";gA/nhPJ>EP_9"?e*m3*UUAT##9i7eS%T[/m$%Ab, S^!^X+DI!tf?cN9@!t*L[2NWOZPRfc=Ao E$AH=\("8?oe15>dT!B]T<ro+:pAF1`'aH;XMr*$U;)p%9P 'Hkj?04I]Sl;j&$(,S3IC8,\($%XND-+i IPY]DU7<HN>s`@PBo?d-bfZ")mOi#$b2J.A3A]Pk<c;`eYeeN7\kR4>RtQRo Fb6G4YJcKB2-i^Nn^t7)dTOdC:/WlkR1IoW)GF^*:=YFA>tV94KRfkYnFApkbb^qLqkc`7 K5m4"$[\RIIYJ-Ys&Qd;P&RmL;fs#2=V1LQtJ[K10n+DYg&ig <Z;* d48"QsJ>eYsEbt4EjPP@FsaUjs+^[<i4)Kh$2fe(`<n>b%GqZr_+lgQ>idEMS+7'V)&=nn_m1%=G6ZLP8XTP'rNo>%[Qb4/4seF[&XSB\EVi%!S^SrtiD:ARnB?3As,%L@_OFhm"@:'/=N*A*OMESS2@M1VpaXTd_ISUSkUO@ERQE`SaJm%V0BX$#WAd9Q>_#-]SV'[:N_,_W4/BeP(<,PA+A#lQc+RF![]Xs#_A1Y3Dl_A3,kXp@OXT(i'M>m: +#b9+IMkJ?!94+p`q0Gb<M341AoM\MbiCE6La`EcY'[j'= =k2>rae#sVoTXtlbmSFt(^3P,?jpp#&H/f#9T8m]UJKYT"N?,36RDGgl(5i#j]% # XE>6l$5^?0&kKs&9h#P-G?$q1NMUXc"Y[Re</N>1,K%2RI3D q8?7J6lbG(>jT??)E/F8%MmcChF3Ie1M*d21#"p0K<UMZ/)o[8A5qd=Xeb`3feWnq@2P0a3JZjdIIJ[;D7DLYK-a1KF&Nkas?7JI_GYrK#aiX`P/sm%a6@#+2 BpJ:&D4D)GI.75Hb^MA #"HRlLD7em,F[bXDP.qXNo,`.+%YMNl PKmbRE=Cs5btD(M^QOP#Ka+r<t]Sb%Pd2So',(=Kh@\_(s@T4H'7(X2Ss$N9g7(CjD)nd4f8)^RS#:J7L=ONW'=1(EDk#t\-*fYQL#S$BE*M%g:XWfFKmX9.c=d2p7A/m:g/9]\SqUb:p`p(TX(Uqq22R`1AQA$571UcW7EJ2G&,%2Bm;K=bb<Jd`3YHV-A3h^dK&F$D[[.'W>n0:Hp?8/XRF! $T%-<0f8c&+DV[ZCV#+;a\c'<+^"e`A8+9!<03(<FU"Ih]^.m8SAAI4gP#Cd4!onbCf]W)678X$(TY"C0=VNoZn_4%\4 #J-j`+:M[!LF)feC)R_1QWW4G'0`C?X9TAB%A2h@P<NhDD`%R&*ak3-(D:%-UdZtdCBE9C1ba]'A$AZI05+N>F">XTr0,hl-+pZlKA(9a\pCQt:QtMjYYman]4nI]-kD@`kO<D#+'42ij=b"N1]!?*-XAEZh0;3"n,.'E,-2RDKfs*$*pVVY=AmkCl-6)GJZ1,O@lBL W6Fm&"J>VZX3o_`Jp#@\q+hJ58LT_8El&d8%.%=o(,!f&"Kca$Q),D<F>BJ)_FNob(/BD5Jp36H;.R-.(fE(^HXHeUbJkN>X(Rb-<o!=P5l,68d'GSP.OGs3O$VL5?a)]XS.5"j!CX'=A2*O.K(3Oe^AU3Q?9Ft0Llm1Q;%"4HM; i,@h':b0Xo/icY,ZV1"W B .c2gXih(2%D(Lapp>V!k1Lth&XdW-Afg$@0'@[bcA52+=at?gA;4W#354d(Un]l`=+^_'P+$pA/4&STiO&>t5#`HJs4V%DTF@j<D]H>/.6Z&U<Kjt"Zc:n`0l^#]OBhO1]jInmJC:+nktQ$d,bK'NBbgX9`)A<ZrZ 9c_#f@*MA$DMjD;qL@(^.:$U+!EkPWp+j=jAMjAFn_+t!V!d_ Fa%Aj"6eX p28I4Qf$FkAfr=X3s3*C`Pr-^re=d%qRsqE;rn4fk[m0e4Q`+kX)&I._QTN\^pV(0:TZ&i0-d;(m,_=:kYtm$^[#g$06k(l+()tKN19A#!QTZ>>'*[da%>TkjrnN3\L.PS>_g#)Gk&fXrqGUJBo+7"oS?U5UeE<n6NGTUJJ3`1O:JKBdYL+oC _`^>'@A;Jo`;r9Tc#)Lep\scM8$--A2C(K?SZlXU0E1M00AJY+?XnhSE7WU?L l!S98_XBA3$ddc"!rtUcTDOe9i;hk1R+`k(?a@K1lmZk5:eSAo*Q&n>Xq`<`I/sg*Lg"=Q_VO0=pgqX1+C^rO-.V& :>rMD^#Mc@-!f--t:KR+ 3mC%[4&nS5!sC`E_W,]A?,5CDSA]i)k0pj`_ne@Fi9GJt6q-d]jJ-jh4PhR(KbmDgL9p:KakJZ8C"?iso4%Ar\5[!Um,i)lgXB6Xl-*U8V.Nm<%7Esb_`?*7tTMqhjqTGh0.3[%6+@dC8W+h(WlR2;27:a6_O$5k3gQ_o(bh*IE0H#E<PskG]_#m1?XG_+L10:\U#Ra7,63fKDN#k'pfYc*/[F*UE;dV j*UkX#`(jJ2@n</rWokA5L'ldIqt/[eAC80j*eV8!2,.]>).4b>9bm<%NEI?N#&GDtP6&N>cV3.C"_:O.=!23?!?3LHd5m> NRA)lO3c/d+\1A[QB`C\2U+57OpQEqSc&]@0AX!d,\l: H sm<"j5'(d"[gHX0Y"O#`$hU0mOkh01NWt90&rAen9)NA.io5lq#do>peBfp<>A1BeiI])fe!\R)]1\"OC?0Fc0k 409tn!#qQe&N@*E[FLpPR3HoY,PS,%8A9_iD@Znc! Kp*gIhA*nI"`>;Tsr;g[R`1cmt6"Fj/Pd#gLr!=8XR\:Amg \")eFXG <]JL +Jg@`MOD7a9Xe)C0oZPBE4ikP.QT;AD=3#d^t3sn1il3qM)!2>\c$\12;!jkUftXecD"IYgtr#2tR*Apj$rRT:*-nUY5]T6o*fFNMq#I :.G\ah3sq#`<QX_A()=YA$;/ 2,C43YL:Gn()AlA_5L(Ap0WpptgOlcVD6B%\Ja,4jCg?5\PsO\m?%bNtAnK&!$dR$&kS]3$S34A]Gc!qFE q o1BM_IsZWE875i"VIQES:tND# Vf<hG%TCMBWfmhtI35$A^]q49nrbnaNaomsDpZ<E@jX&so_PKS*_)UbsFT\4A\@NNkbN"_KA7Qt7LU-TEte!XE?iAL_ft_;,rT<cJ+)U<j^TL%&!Qac,@ET$i%>7mT[;2tW;U(Ps(ohs8?SStj13fULZHM2&-[9#/q V\fifI8dq+Bj:NCjEpYa\g<1ef3>cBJ\%8aklFb4V<-A3CW/+L#C(9r+XoaMar ,C:t>6r[KYT3XC#5Sr1oVW=q'/@58a@qD!/X)A<dg@Vp7"<>A_LrB?Z^V?j=WD)1%eD7=o9)Wti:`O3"]r+>KjIK/K+3+ki11&ciJ4+p>`lA#]p[int1`QTg1/K"d:CmhYG,h&@F3#>h2dZ$kYPIT#Bmq6m4f,seO5R)Xf1Fiq$Dk[kHP74lN>^mapAnWrCiSb4HsUYAYr++\**e-%UVjtfP1S7$K)Y6 0 &;OPXKY]L6Npc>SRHd`?n#A4O3[:tCR4*!;&DQ5c0`lL!])^HsDUJ #<t@+c+TaG6ScmA="V/,X%g?gTs'`acLUe.`kJ9!*$=!YSjjk2<=@ZDLlP4sEJd<T?dhb\%!B->&ZO1bXbe1$:q;/Cf:bH57oUE]H%iJ6H8^em60DEeAX6WjXhV0_MiJ]tdAaH<oh,]j+P"R^e0]sJ$AWa?XnK]hGCsYgk,ht]_7])nX2*,+?3eSeA0L^.OUq6&F^[IdF%I#ofm;/J^W#N6N,7(>o-k8\6FSN(a K(6?T($;dRT0Po5\MJOXqg^pVOI[.W<8\3Nb(s9g_-P](("A_3$Ra;b_tSYLb W3RKP!_JV9],P.q!O9>?Z0d^53"Fi+J=bf/0RFnPa]'f"iY-g\QK+ir!K?H&MK6K'Tm:[>+j7P?/>mZ[s9(/$=sU,q787+2bY U#h8<,qnUc6tt3nJ[d372 (WA&*936B1%+9m_]j8m2-Z4OOHppbR-GXQq!s?HhI:JB/4,AO1+b+CtmAAS.In[)=AkLOMbmcD ZP%sqqHrj]F*BeAaso=.5F#BQm7[`h'3l\3Y6&!S2j+pX"]Ma8M; X``jhK(5<%Xm_(DbU^I@1m6qGk0`2hXH5T4Yaa/#m`+cI4UiGc#^Sdf .">A+&!A:gW_MVb-TC/S"c^r;9bbHc6TEtWemNqNn8bbDs9=pGi7A(SoT2d&=Fmo6W!o'haZL>GG`9+DebsocV9q_T_g03?Kl-&'WqE%>sn`4>cA?_@-`p64Z.rVFfH>t:)d#Pe7B>oK&Z1]D^A"A%2`kh#>_[&o/HXjhH2LOC$fW$I1(.?r@VIH2sgDa4o4XM(1VTm4^!Ra6`AD6T;U9d@$;tNR:]4k^ 5l359gf'b"AA&9)^.r!>hA?)]]bW5F>U&Si$ss'7_3,6[`]Acck9AC8Ca\OL3bb@fdQ=VS(G=ieci2BBb_jFq)9L8>o0J)DAL4<]VG'E\a!lI1aEaG-$(3`N 2VrDrQm+!>t_O-X`Ze2 $mI9WQ2T+U;\1P;aAgAHl<i"40L_(Tn.U/97^@]3!EP9.!cG-'J57-Ri?Ms0')8A-_4WV18KJdI%.6W%nf!0I' #\A\$lKr Xsn#T.rE)1"1MW1pT2QcY.Yj 5YW_?41a`<H&MZc!9V.LW)J-8R)D:i#B:;dHF,O9#H_m"U?3D(Ml"BY$M1;FK(#k!8bk3[PBiB?Fq;4Ka]FkWHOOL*kcE\-<on1HJ'1<>^Jn.;-@TX2C.T2J\R9A*--2kjc_X&sk8r;^'$AoDON5=bbk6?1,0rpa#+R&?pGAl8f@_])G@lF#N=_ 7cLY[8JYO'k%d[XS$ LdF@lE4Sk%A_AZbP^7lZb62k3p0?XR$q74j`Pgc\Bkdt!3CODA5Et&8@!:A&Z7B4d3q2'ZH.EhAGt;rWYYo_e">WQ#417A<P=Q.$/)#Z;W.->Tk%'Ro,pS5;`5'&E'<PHZ$\62j3+>\XK>2o&B??IHl,4Uf>95a)qR5F9;Z _AS e-cWA!;?Qc,UiT?iHdY)5rQgD*:"-:* /l./Q%&^b)_`h@37IGR*P)V0Wj0<r[]AKN-d>.RIS+t _UMJW)d^S[snLfAocTL(GIB6ts4tr3%Sr6^S&P8:npYaAlVC>n*D``6F)`7-pdG+L:e_e7MnrfSJntJ GQISBRm996%%X?c<l?G1T'A@'Ih!1hp9U*[Rm,Y<@l.:'.i#`S0,nW6hKGn'\):IB#Na@$,5JA,VP5DnErnN_\>tKSm0);?L&`D0E`[;\Rc-9c\ihT/;*9\j'(V"-T@#>lgS$0]^Aj04nKC$<9/D(2K\od'XbO(J5F9PR6=BGFp#3l[p"n30&NEQUe(OkEiJ8%)BAPiK]L"6eM7Q)VO)FE\bYk;*,R %,K$,^#O2eX7#dEKk>]5(Z_p\B_Al`f1HMokqnGU)L8&AWEbl"?495+.`>IO;o0$d32g=b%W=n[>9Bn$iaB=Lr[gP3ZU6;htm_J^EpNtWp;;9cXO56Rro-'<r!L?`2D:K(/b9_eS&f$AAB0t  P bh0 %^X:fA#W=$$qOZ$W_O_(DVXBMrUPA^_iidVn"5CH%9`bmGMC+"C>13)&C?tq_CX[g'QtQ8fHeQiarjm3ha^q>L@Fd`A'Vc$i!FiSXKDh=*Z4(d6,`.+K>Kq`Np%`.4TZ*d-BAI#/q[Ns+(g(]0s:X,A08)o7ALtHHCOOL&@NqhmikX 8,>=;]!MCea7RC'0sHWnW'L,7E7'+o$A%t2Ff$$a(pZoc5_76#cs76&,b$n,XO;@M"5VRUld*"q7D+s6.kBY]VbTIQAB3PePkO9gIKTSVnZB&0m,AA^?_QRkk*\;:;UiS'6`N:;2.H85:h2ptSR`V24@ H g&F)&@T]A!Z3EdA\L$rnd &D9TN"hCrMls<r^MSD"7SKAN0D#NPe1n<<;e/%fhZHOrV"gLe$1j8Cckl=Ei0\#tpYJ?*pIXc7W,j7r-25<+K`7qh$,Q?DGdpNA7A+Ph<NfHb+jC)UIUt4GMo2rJU@BF5F4RBK>UiJ'Y9Lnad?8r^;^;t6Did,l4\5%jH[;fPN(0.ReEQfRcidVVY^lX]F:71LYqL;A`m$M*t<g]c`hKg UrJt>5(]c5d'A8%"7%!r'mtFDUj.+g&S].*+?7^DXAL[s+/;f-'#&sk&Z*"b\pcchVBdi*7k-Xf\+"-#A-AlbL,NfbcUf6">]^*PmcEOGU4SKjp,1&(]?/.rqk%Jr:UQl3H!X iHpMOr4)0ZB"-0jMqA!>21F/h@%_X$&)Ze_R?_AE$YP6o`,\6&L@tnB#Ja$n,YOF1;e2AZ6;>r9+&IWK5N<3Y'5 GrJcp)ZK>r`TXr%8QWs_m80GnWE[L%geqW7P_6XIq!-'(imGMnKg,ZOUf='#d0[b#&L<TB]iRhVkR>F%'kK@`;/edX)=pGqsjOnGG:467Vl&r4] SJ<NVU8GJ9IL[)HAh6a=H:C>%sI%/VQX#K363QfJ,*YGK(1hHf@G4'lTTTL9>>[T%'I3>rAG-:r=GnFE41HgIo=&PT[^BWH]M-!;W=)Ad!.MUs@p#[:>lmd9&^8 ,T_iP9"Tj1ItmHC;-Ib'[r,l?RRV2$V-j[#;h:HK*P8?l+h,$#=t$D,%-Xo)t2#)RZr:>T[i(jlBc)E+>iPIP+6h<Xe\\5FDAX`8@]aGHjX[Uq2k`tb<DZQl3Za%Q39bpPI'RT?O[M(/UAdRsOEqF6A=6#&_G?aeNHYItHQ"Sat2R+jpA`,RB#H9'WVA(45m#,FAR9&*7TK-I$+UgGmA+R9 PC%^hcZpYmO4f%aQe^"a)DC 3@cb"p,>k74K<ht$pKfm #fBm\3J6"!RUb<=g)Ob9@YV c7;ZZ$3=eDM&`HY,"J'7Q=`AhG6m97g(n=P2#e>WWML4<r38Jt-n@Y+)@h%'XYElcDEFe.dBU^J2/*[$3'I7>*3Lq/<L-5;cdQ22>#6[bn&_GsnLPMI-+cl>[mNdb"nl-$W']\'KaLPNA ml]t^WNOt\W3aS\7]"D5./8lS'5g+Q+<?pNBpNe&M-^g/fL<r!@@43)&t_PR52XG,qil%WH=^&Dqa/^p#Xq;aiNgpGH@@k%'VIOgF=V(fbAWg67@ i+)6W^*;nB!sfa@,"e()fk=""j0&Mp5<`KUNmF*bmWZMT"QY(^3'1L`g&c+,-1JUL#^_4:S8a1c^h#_8!K@hUa>hlZ&mm;OK;f"@%s]qkT1n$T6AHtX0FM^en7eIdsKZ<60;(:X<hIGAP4WN<APS"*D5E`]0n[/nB^)AJPf>88gEg1W@9f&[Y#j!;R_\7K">Y"35C0IXdi0O/$/jm(!l+nmON8=2T8fe&Tpf@YYJi;BrB9Oq&5gDl'j@9F4>/"5J0/Wg;ApWb::fBpp[B'MCUCsKnn#7Uhtp7BqAtS!9f(@Tc\>pYD& Cl&ZY*:5mWKZ3jDVXPZ2( U5KbP]\)#qAK-^NjVd.b#'qk>#F.Gt?ZK@rVt9FgG3mQ;iHIe&m57(h5G9i/8n`:G&HpfXLD:\g:RXg`P)X\k\V-`Bp8Q/[UP0<?RBLNT5Y(!"2fq<(-/q?>OBCCMHY$i"X61b>q.Y^-7K8ENOXTF%A92nmd>72e FEo(JD?ZNYM80>_iD+1.R^H;pK=AAqLFXnDD>'@oV5,tZ6rpcpAh_F-$A(ljbg-bS>N#i5 j%dT6I_[?_$`a-*)tAjP Pf$e]ak1";1#G/\k)%+c[/3P7\[qQ:\cAE+4M>^;lACMfV$_d hcesHeX`,E7a$_?sIZho7V&49_)a<JT* s9EW8"P_\!"QD)_0\bjUYH!80P)l6:'isq!t4c(Fi6Q>>X9]mhD""gYjf[9K1caC:Va$SPl_KLHR1jo?Snk[R-l$`'aWrA@_Iio^_b!2ZsP^Vg_6Pr`8@>BdRtLp2_G\#iSoJiI^jAj3bm[=T"<h?:%J)4^:NG3-SQ\'hOC/=s7mo=CGC[=V""af2R'=)]:f^0gf:e]"Za^>@Si FfG?o&r(?"gb>% =(jheYkR(BWC_H^Ki=1q-aZ=g*h:Ls! =EMTN[-n2 [MC9*d$s2tn'@0fr%KBG"6k784fZ Dg%OTX0PpR7Kb O5..q`kZ]CmirOg6$*Es#<5VXV,Sd1X*$*oo.&ak3N+g80Uje[H0$l+\1I]*lRi)6=h?T9FOHk+>)JT#a))fl Gd#/"!24O6G:6@PDQm/?4k_n7%[!Ei2Ap@VXmP_Agm9?=F:7WeW $NF\3C0%aI>G.ZNDQLQASrn(hjfH,.Z(kp@:<e0sjtMrSpU8WS<PS:Dng?D,8mWo._BL^XoIMU0UA"D-TYo=&pVOLi"tk2X?4r[GV6j*I"G?@4'&Xolk'<.ORsC79L^DjIj:!'C7q3'E`CQm>&jI^.?T2rLol<;8<ngkr4&1']A^?U1^<j,.oAsdf-9%3"P:%f:)koC-FMa/<se*FN+Y31l;(18;>o[P5tS#U9%6Z0UJ!dqs?(d7Lnm<'K%_)m6n^,IY;-j'OTCZS`A*j_^b-G'56kcZ'IGa^kNJF6#.=X4Y/VFIG[19(A`"`KjoTcQHfL9Q^0jkRNZK5I>'&YR#g"6.(A3nU?OIcnd+QL[&jN!<!g'`LOUoTWPO3/W^R^`#a]'En5)=N,?D;TmBitXdG0OG!JD=5;HkkOY>AVN];igf.:E*>tRBO:S[*mYjhPCJC)8Qg2$s+0AKeBd4(s1eZ3WD#_bVo'6m.)\&c-?V+f9=&A_j4L?9ZQ:-c'pW74U%r.m#DEH8f6F7H1BLDqa+eIq_cj&T]dr DLjep+oNt93$T10 GXAaL(Dsb(hT&(:FTX,OtVO\9I4#2%boc,0Gh5p(f]'bU$L1[0ZBkF#?ogBjUm2oQH]pTinSN":cD_FaEkA7_M3\*:Q)^WUREFZde1APMp`McO8pe^:-^Y&H9QR,#+n_JO&0Np+9re11>)YM]fYAIkCACaA\3-7fKIFfY7Xp[s\oM)f&*+p)pFXkpjGUalhQsV6iCn2iOBU"?19Ns7.m-_kh<-qI8OlU3m<\r;tM=]]b,/.]'%Lm*Qg1%jGlE4AfWh5TR,:nCU3ob!)XMF@^2%s<JY"@\>Jdi,@/Am2Pqgsa,nZm;*'%^XK3e9R!96eVbt'2GkO+s,%\F1Vcg^W"s`NR8eM$?&'MA?]^Kj<@nS75,jA-V,`;<J;Lj#K>=V:=p*@L>_Th2>&7TI=,.m;XE3142Z#0$m$8&(!7EC%J<>+$t#-;-"1EVJAW,`AkjOtXb:;IaS#q)lDk6J_DZaJ-P-7?]MO1XrqU4ad)G.lD%aH4m[:`_Tg`5^=Dj_nNSfQ446ffRC<t@?6VaNR/1fk*@-$qb%t#j]aW]n)EG5XJ5:K*=M.R=)eAgsTL@OQ?m$#6t@e-eJ'_J'1BRLF=gWN6;3S*CHM_iBie]VGUeUGI!.0*DR-\-[9L\mWgN8ebjtP\$S0?_cR??[`HX',O=>c=9#Y.j%AtJ4l:+H2oK`*5;d9mAIl_J5LX$S99sY#TA-=nB*G^m3/#T^"sLOb4Lg6(nGa_'L '7$i;bdDq'j@j5ME_s1BPYWDn!j2Z+MtB8*Q_V#ofZ7Z$?K\)g2Nrm@-6S@C=^tSl)`T$bm2"p3jj8a^UlME$JD1#.XNRk/$,A^g-\nj5@>&!-mhJ*XYNKHps?' jG[*S"<piI0HQ]<)ob]%A$>lgP$H"CGQT m"hkHk@U)N?"dVp!I(]]0$0;kc:)Fr2DsMXGZLWUFT.s&U@fk4$L5F*j':N&X(DQc.P]p*0ai)'5=^6r4,)%Wi]`O9,L`mPj,pJH)_S*IoN%X\[X'A+RoetZ*q4b<^;2I85HAbh%l5kgAJ8)+,bA1nL!H:8&F';1!V(6D'O;KDE&PhM8oRQViRNV4%Vb@Ab]qpP:Q^i6iqW%/'m&kBK:dd=j58ITNR+CRgI(g1.69cq'B+'+0Y[5[ti=]$0Pe9=7H>s$oZ,6,^iNoNJtg8,SkCjpYOPlSoZ3oP^KF-s1ME@)n?U*KtaWCpCSAFK?C*CGmr4;hCMd3]bLI2%]m*4'aPg%K5He #TLa@#%"_!KItS"4:;9lZEoTOSI6['*(_I^@qFf0+Kc=f3E.`(0hiK&C!jq/-@HQrk&8T*Y4\S!%q"-1H(_:-\nR?O=jKMFfFin0LqO9#prAm#%HHt[4jXK.XFEH?G;""Q0O\5>;jWL;5@c6E;`61Ne?G'T+Xp"-n7pF=#N=@@ri<G^jf oU\UK05 3*>kG,/Ze-3hB==Zs@:OY\AVX=_Y.UotK-X8H;Hk'\U3+dg?Y.W$_Cb=KUbm=j(AYc\CZ%82=JWY53$D2p_qITtj/.1M+:SGC/b'RJF67h7X=gEREg2[Z[9LRM$fRZ2RL4"r!`AYn+jVpPT kPZBHSJUq?AL!fBo`\ ToH1XVtBL0(r50hV['=UCt7Fr%@&e2K^5md;r30nn^'BL?Ra^ZWf&Bo#Xa@_FFUics@m[;tt)P!43p`hR\@O:eYqdAjmY-K<D6ZP'U,:A&jRGH/a7-LA(_J$-Bbnp%Qd#WEtd1HEq@6=lLghDO-Q%CtCfn-O:W*L1T-QK^ptb':`S)`]l7o95VbO&^CR`teXGj\:PAG!p;&3$_a<:a]JCgK5qI]TE$ipgnNJPV'VY`i93SbUqEL.t$O``NT<+rBjN V$-G5Dq%mO^AtlXC5b;UpaOPgUEgp*r"QGce/3?8q>7';gQ6Fqp/rKqYn]BsMO.-UaA$)#=-b:di#ZnVaSG:)*]AF]]q3L/0n<!AD6bAM1NNR9J"WjH4-^lnbT]Jo>GU"]2E]MLh-gp4s'QhQ0;oq3WOtNCi:ZQBf,_,"3Q;T&] XFgE'rg*;?MD3`*=N-7$#%nj9sUC%XN%,h#CA71ZAk>q%mKB0mO2n.I]h-1I#+!Y)n,R:rdpBbZ[BHlAV!q2cs+@PSb""Yskj.A81 A.rqFgiB6gJpSc.V3N\Nb&jJYI<(+%QZa7dA<m2MS/'R0\Bn!8Zp^0j-hYAjA?+iLbi)*rl,.XN57Jr0FZ7j1*o,#PD":h9O=tD'REC!#CpBP&Yk]MWm`>TpLH'H:F^3FS;YdGY25_U PeoQbr<>J<+Sh(`$P=kcM"0nV\O<OZ>#%lEcGnrN_=X<pG_^5Rfk@p2UPaY%&Q4>n?XBT13k=qq).!E4BsZ2"pqrGU\;l1<Vlb',Si]XHN</7X'l=SfIUMG.RaBe,`$fsp@Ug+H,f<)3F`ge1sNk^*Z9,cAS!T1@RJes"64iq'p;T2+J<'Z59S.-6<,[q?gAL&kC`I*?:RmKgCOsIAW+M5)C8-POb8BA"-JYggeM[-QX5I<8F#!g2H:8LDTcR4b*K_!@e#!!SXX-@='t5BG7o,QJ26>r:re`W>b'.nrZL2I_&S3A4OnVW6V\E%14qSG]FQHi?&2);SqGFPZ)q%bn!O<A' [7m*@$Y@IpG-3^p6Z3lBq'<rUH%^CUir,Nt=`ikL*it]gsAn,Cgd_SBW\s?=l=%D!%^R]Y:]_FBf2\,Y?@Ssfb6FKNrT`=]lhPXN/D] 8kTXTJ0Y`WR!jSp!M"(9TK,$s%=e9QT=?rQ0:q-; 6K0#@pIIYSfO3P_&Q7-,OaT?EjZ 6i.5lY8Zt7-0?0%D'MD4\*XE9!2<6@qsp-E,VkmX<RUUnTG>s(*`5C^(*>0`8f5.D*9CFf8,C3mMpmdn=5E!X+9Kp8'HHc  [%Llr?t-,*RX59hS4_I7gl;;k;%qG4bKscD+RO#go605<^JCZM5pBcdA,oJd'75+Olr=aUe`l>[rL!36J" Boio2$`)Kl-=Mgge*+@Cssq1n:7KE(pZ,2$dY.AK[ D9qAKrjo; ZeU:Xd+q/-KAI&1Wa<VO*Xc:Y_QU:N?sXKCd]R*FW0\0L!O"k,?C9*r:$5f=oO'g]-o>UhsJA4i)R17&_1LViJ!EDpiILQn^sp*1"$s(^+^&]57\5A9G,rI_$&qFSKBff/)WBe!+6ka[k*YaKYG<0RLEA,t:_"g.Y5A5LdTWl"/_UisPLQ:O'Y8-_`.4&gHYIj!1#PfbL7M]g:=hT@M>6<i;+gpeZj&DM:n.3gP/,>%1-t,!2*nXtltI8#X#<)T.L857G*F7JjXq3:n$5q(Ad(<V=+VjV0A<<0thM?eA0a!=8rrO'D,tpXh+GbQJJR`Y&g(:"D%`V<_q%Y+s;R3d('E*]+d`T.ALoYAJ]U5nsXl#W[F+[\n>8>7J#H=4si+]U5\AAE2PP/h*!cEG?JM0:8_5aC1o1.cI,h'd8B%6BH:E<2"]rrfbOEZ+=q4t$@iU2hF1[AmRg@>t=r);Z 3+Hbd4PcHV*i@Nk_EMD3?Ct0P?d<#A:5W_!F+MG"&kK]4j]-Xd Q31oql;?O7Qa9t@bNSe6A%)hRO12E@VNcsSf407#@?#92KeEU2=b<SY4L[?2mL5*80pj.=3P)9b5/Ri0[:`lmE_LkT5]gLKa`\V> oes)XZnaDg[eh)3PG(*G>DB/:^GsR^-)WK<&BA1K*2i8gd6L"nn2 ,8Z4O5[B22Q0p"r=T .]Mr6AeC[qY?5W)<t:nIU#1d[^3i)?U[nd[psX>d,72#0:\d]T4LM-2d1)>79[4qAVkE/Z^aSB%hq7@UL)iN!Q1=(-U+2WIBqO_RU\L$rBJ(q9oH53n9kBB5lr[D1*/fie8Q?LB\M^0dIih3Z*^J?)Z11k@,sa:p59]G""sB#2Q;LX@?Y%NBt?t8?p5FZWl_S(g[!U`oD,=A^_]3?8n'FeY(>,kqnsFAN)9nE>;YpIm+#\0lD/:mU0jDZ0+Q8BD+G'oAMtV%EC>FNl6Tn,714bS2_f`X!lJK0JikF#nqYP8DSi&d0+,%+CVq+V4pOd>Se5meYchh2-f4Uksj'3R[m43qh!'/.Z^3j]B$#CJZqjWb+XLUM&-a`^0)b>g2lFt3Ml%Z$g"D(i#H]4FbD E9G+BtjS?8[1ojO:";nU1s';M]F[8DTpiNP7iaPnr(/&1t,EW!f Ige-AD?U8EUET:3YB= &,E@JT;%7^rdl"-1A-@YLU%?sXNo?r8m,A[-H/2nS6#jEPYnV%?8s[ZEKI#;th?Gg`=[r!O=(PIh,TBX(g_14V[jS*oaF=I$]1sbg[.L^U^;gh(YWfco8K*Yo_1m:Y<9XcMf`cd>4B5_)2tP$jja#:\4!Q&4b7GY`NoO5)l:-NSdZ!odhsA<0YX:T`=U,f\%TD&t:"m`> M!V92(Df#!`WYAoBl/A#NLH"XGVXhdmrjc+[)dJ*dXK,\IGLEm)lgX-\MejV&!G=Y:j-ck52qU]f:?rkh:i7<OD;/I$4a:cAfF3^[WHA5&SP$$p',\i+GN.q@!-$`L#&XN\^sT-BrlDh:PdqS!e7`WBg9t# Y6rq:T@PT>?2;1Q-l21cr[\o+JQb/1L2)t5^A(K(9BMK8ZALi4=<=tND"j]nXAgtA(i`T%!"+;A)nFJFVQU)$Mi`Z:1]_AA[aVB@XD>;h9_6WE(l2Gt>I:nBrLcj(nb@GM"7=g=S T\M 6Sqi_o/_)cOr]O:QDt@qk`:jA4tO^+:j#MPV<1kV^;k:)$;)_?,mGqe*AY8#Ago.k. #OY5g:>?g`$qSg+7\>3k:ak*qmj; gdGUiig&5U,BYiB?$QXWArV4Kj*DB,%W\1*9ES^lg^=HB>8qa4%Pol\nnS8*!r`%4Nsqr15g[*Sp[--kpIAq&^N<OKL/OB'(rOcp.)'AAAgj*FZ^flc#UCg?%BjJ+>b91"\Tp_iT^&m='FeOUT&X*ni*rD\0P%LKUetBDK3A0^^EX08qjg+O2Wrc-@U"`M"3R291mG[$7G ;>pnbijT<Q]2lJnBc@@ra"WBtAUh"+Go 6U6,<Ns]kheJses]+A>)6F(,$e?88$sX>=(P;!]7e(ht0^MgQ``%7KjDdCmVbV1SLTeWg7PE0g[:e0Q+,4VPfHg+k78Hm^0UO:Ea$>AV\hB0c\#Y3NZiA$i(hPh>PN@s<X+e4SOTp\_o?B_7C9t=LAaM>_bKW!W_El%bNg^sA<)b*p66]'!R*Q9(K4'&YfSUHY>`J$0X.Q.m'j _%.LSMKF2 hcael/5(B=mNh&#@7pb'ZLR[41U60[S2L\Fn<pn]6AZrM]ip)-?T?A7B[dk`7?e.CI-9a$ejs%(&:bs,HV$@C?.=2)X39dM5i!`;h#@hn3AO/ pmFMOpIGA2t*@>@eRM_2X+hGYM^-7[G-^h.^4m_d=(m]5DYm[g 9)kF0/=]Dog=hA`@.A!0&'kK'<dg]69t`mqqT!q]K347>#l.2,T^qBde&[Wq2F.bl@[(-?d-,l>[][34(NmM8*/l,m/fjif[+b'7gn#A!8+H)tiOIfY-VqEbFZ_*d+(Gi3n^cWGP9"I$gpO)Tn\@m848(OA=mL'MLD+#aS^eo.mA0cDK@Ug5O`ig%s&b(t*&?T"O3RE;'g33#cEE.Q>B7Dl"&`\[DF;(RL8R9@%l'e4s$(;7Q3(Wo@Dg 1?GW>,B#9f(48d;E3nkY::p%B?E]4rUIIl/S>_Jm)dkbsPX]I1iedL@/lhDr+!)O_):A4=cK\S.U:*t%V<cAeeA1*5[q>?A3hk!"i-Cgl=KA6Xo:/DJ##(3"Nm(Dh+j>tg;ORJ.t'W;1=k.C5W1sm^T?g%slq,RG37+!"TtcTI$U3UA+B+=O8'F`?mh^5=beG\9,e^69I]@(&%moD-N!12*d]<.7Glqa!*ddYLqWLO5j#$QbW0oJP7XXJCRG,iXOM9&\=[HQ"L_I)^,EpN$[A@0&VdqbX`E[`UiCN%PZABVibPN)U&/l+h_E%h'%!t^k?NKmL9?1i^nB\OT?-_+,`*X4'OH8h%\#],cmg1Mr?M3elTGrA&po0n.XNh9Fk*>h$[(Ol cr-K S,)2mYCtm$HqMh,d(3$Q-Er+=6S\YWS'2tE(6">0]g3D.9*7t O!rO1C-g:JTq5Fa/>MoASLgTj9FA%b<sBjKpDQPe8HaMe4(J70%NpK+A&_>*%I\Cj1.jgkX?3n:,#WmA;@EUAEa&bJ$?=5(D.[*4F2ReSk8pq#oOWCW-k$1ks=<o'B"1DB_32:OW)fXK+hR-BpGCdDA5iXgdIa9s.Od6n-^L$A+J,\X4;E(h$sJYXmDel0FK_.ng-;-bKZlY)a-=iG>hN q& (PUA[]iq(elgSlXbZS"I%$iOcin8,_h<*!@@N\raX+JL 0Ln1GTjgIj)d,8ZU#A\<84AiW'@s%#FZ">/ #JaU0hgBgGB0!Qc_RR&rQQh*7 UR3Z9@k-(lDP)XnsEoXt"An-;LA:*4KrF*13/-n;Q&[\U&X'&e97jkU',IY7AoppX5nK<Z3k/^J)A_I`KVGU+X%&) ALWm11a.&;#V&7LYm?]h^"?$IblT7cE'ioPMr7APS+?iaY5:SnJdN?i$;hYAooWQT-oT>Z#s2JS_na@R6ZF2m6pE+%-"$6mt.t5\/:rcnO1B%KC@ r4sr`p0'RoCQ=lfNam6;^?dLp<SJ"di_"pHp\=@P!2`)Um;t(gRmFcqVUc[FA"*9)AbM,-!Z/7Ge@Ad8e<WP=aP#SS, BfpOcB-Sf1NH# #_,DkoqZk8?ADO34bJWaG*mdBVcPt@N@0nH&!!=3:2'["U_[cA4VYtFt6tLQs?l<ibB_:_fi[Us\%@^p<AU8iI<7<YbCKP^ghShis6,Ob;I ^>.'3SX;-pZJ?b,kdd;V 1#KB8WX4`Yd?ta$5CGBdo<U=Tjd;KI?tN-6hah Jj&_FdV'K]M$] r-]3t(++pSR&Pg$f8R<`Al6=RrCR#3K 59r07'5;";`;_c6&0HR [,RSAZ3%<1G1YdP@="),VT:Yeir44h=n!-Br-"a,C,+E@WQ$*%]/Tn`?ZX)=,3#$LNQboQA<!n6%H"YP\]mB5.;NX1pe'?`\@$^BNj<tQ/8-PpUdj_Ck"=&FO8EV0 ehmnK(Hk;n:fq2;G=_Yg(Xo8sq!*VSd5qfW!q6M7@nd$5ASh^2mm/[7rC/k4]5^>1" P+tR< ^o<i@X5f)\1:5JUnj+ CCbeK%jo%Ne2bDfVj;i(;*)7J$6g)BtY9<i!_PI@HYZ^ %[kkK[hbds?-tl%f_:_lgeXGnA5*JtQ&0t<'f>q-F=0-.J7Kj6)nmq9H>5(BWBc)jG%qIn*INl`TI/np<d'%:lf__o"[jOsqiWUa"1hK+"bA7`"/*+/6%?F$n,^rGfc?.&c\iFICkTtQeBgiR?_9g/G9:N$lKMdnpil^^p==U5)5?7BRiM0l?b78K"H]c%)GF^dR<4\tM"qfhWcKHcJHPH[i7a!>hUP<4<@19*b(^]?:KTZ+P?\/GE`[QMki%nfAV?A6l+(g(t$O`\-2pXCkcU 4p]AY;-+khk6PoZ>lUDbnGJm2``G<h@p$t+39jh;9h+?^4%B=VJ<Y3<</0$i9Fn,H>7^'I(_B0^ok/>K!iIe:rE"5UGl1c-;O@Z)ctM#Lft\65Yh<@c#js.!]J"c)jQn\GBaetQ[0WIGn$P(Y6;&:*QW38ffW4DA.Ah?;#-mJ)gi1YT@!fA?7`]Cq>[87HL)rgZ0hYj\<Nm$;h7A)M#PS?$Iq!oSjVCqpaS#WIi(J5=A^c*mX)/#S=%UI-LG!pl -(!pWW2#XiqffEASLdN,(Y*]FR36OZ[EIcY<q%S\?dC-]"I.,bf+rdB)RmB%9I7q8>/q+_t$%+.E7=XB`.PGg7hs7NiZm2`p)PM'D]*e"Y]@-a/7+)DAH[KJ%1?rGgE-G^B1EKj&'CE>-?`mdXs#"\b,P3LmFqOP^d7C:d,4OT2ZpAfBt*^]h"+Q/:8e.3AeW_9;4.fDW@]!!^!tIss`*le='i?_4.F=/L'N3<Kijr1"d' AO7(I#0NIjW]*O-P(R25<&`.7+qm^kf4tpUIJ[rIn F?k"]9mF`""k)%Nn2-+#Xb**5@om2 cV$KVc((.,&N(Sq081q$cI]"U23aRXeOOa7/KcCs3;IXj)1jYF?AG1\YEL=Det;,8Hi\AmQn`c1O&acs=]*0'DMfdA&s4DUl&qt$a6G*/B?'-_]%Jc%!gW-.@be4R?k[M\ji] 8$srTOm'U!jP;W<$pXL81bm5Vfme26?m3as_4?M/l6>(B[d$aQkA%4%+SF4Jr!AHRTWkLNlr+)_H',e:6sEWnF1YqAiDGt?(5Kgo?&aP/t"ZkJgf6CJ)&ER&^44_dnjZ"> @`1L<3f,*t5Us(Pb>bKLBA[*n:H5MA ;V='WQ@[iBiPFaWcj"C\=/RnlUoJ-HCTgEt>F,l.*f92ArUma2 3m5oT4%N^BS$=$_KW/pP;bL6E1lDUPM6$F8OOcI7I?.d>*E35",<tIg/JU%C/T!sWa4:;ohiZ0,mXUjpC9@b?TJpJO>9\>4R4>^8i=/H@%_*iXi!@Rf\akh(dl+#rsRJG]H)B5"+QEC[1ci,I8f`(QY+>Ws..DmH+/BDV@9PTTA5!?nKhVgAF?['JprQQEC4^@16rgRqELddHHoSl $:X3HCrr Sgi!AOG#TNg&*?r^o*Ms@< Ooi]j28T)^C=II-tdag0=:oQn&>)E-d;+mVrWM*mH1d%m@Jk<*'F$I@KJ>.:25Yh73gOQ!2?<AM\d+TY?PA26qtE$5<8lpqreQIpk1R2EAq=?+?P@?2qkfTPq^J[cJ+S],:AU*kW6A.IY?s8sQjTo2^_7m7llAi&:rrl+M,bKVM#J%RDlo;I^MZ^Ab[HS&)'JTm]U71fW=;!e<W%9P=#/#_]NRY@C)&W%s^4t,*rFtop.4\I&$/NK96VXVJ?aFY'A$!<$f>:O?2a=/(G#)\X#_rg35abm8rBj8K&OF7$QKH0YCp[D*ROI8F^$\"e[:rFN2J;W0a"-Zqa?;(Z1CU5;OdaHIULE$`^O^m=A5t &Q'\"0U#i\(EL,j)oGOKmU^b>\Td=.mn=9\EcLH`N9&jWAcsOE2!HEkag7:LefbK;MkAA_!<e:7:N!-T?ORM)mY!*^$!)t'(_,Hr$AIgU0@3EJ-3%hrNtq]Wf`p544k*WPMq#XB[N7] V)4ej[Bip(X(gJ?=`ArpfY&OK<?(6?UlD3jR ;,-M ?a*#>h?iAWBN^Di_6R[>0n@[ FHg<_A_-&l:HNP!A_j $<r<JL[H9]&IC>"]s`Q'*7dRl'd%F\B<N*3c%8>&P.%Q?L>q)\]B+ce )qT\KRgNNHQ#o!-e"X/S=(I2bDE3)FV&4:fKY:?&9;nS!RALA>q^\FBY'-4[>lQ,?]#3/8F3.8;J/FG>$0,mJ3dJ&hi$,n]iE5P?Il*"mr3FQ Po-=<)id_<r5!A@AgD3NF$+sHqgUoHj55Gfr2rGhVSA\Q9[P)2f]911O_5)*cYcY\KNM]V_YACfZ1$!tRADrAWc>X)e/ZF!)qCA:#0<M]`/ h33#GTP%#3X4l@jE\SX>Hlh9)R0L$P1O3s(O5XjCK +$QRLM&Lf#\D[tJhQ0g2%.Et.1EhW-I$@8PA7ElQ<D`F]FTQ^0lC^&)_qn$R2tCd_-pY#7B#0d-h?2mB*WV ?pD%.">FTX4 @Z+$[0ER'AX.T0A&m[J%F=lqa,sP]_2,KG6J;AN,EpcbjNpAM`HP,F2W%@,X(/9s7A1.haE4Z#FV(Ut ;DHrtNPr;p_V(@9<`YlTF2\`U9Q_82c#!(]T;r0&= kat71d";K$:+LnaWq))=ON$KV:rIda\(@Anf_Z/I:>&-k:i$jn-^O4!j#NfEsGh[#"Vq%5 qn3s3+)b(^.Xd07Qd$dL61bR(%V$D!s<dqo86T"f66 c'q^/lJ[1/"o:$pLILA*rA$G9R'#gY[OJB=(3\HJlA1hMdPS-[(h!9)dbDp/MOl,_:ebkl+V@NbsX\D%6-_dp3-Fn+k-,P+SG "kA-h3C;<Z\/ae2k1Rm1?g/$NDZ`Of/3(V].(.^j6V>Acrh"JG'FK&r,d%[thtZ1Q&MgV 5Aa2n6jV+Mp"?& "i8h+dmKbo@<'k.<mG16:-qL]OlOU7ICRT)""d$TBd*&4jfgFUV";gGKRK,dNB_GL-JneUoW`*#EpEVi5."M\2O_<OLAMV@9+C&VDX0Yh!*niX1@0Sfdf4;oIL<HYP#!#"?$mn4P>trdH3P('@$-kJJrI7^.*$"Xl'Z/C#eQ_7@8dEmsQ\L<(8lqhf8OlRSni=T$@'FgGqBD=Xo"m^O8bJANBdn2$78Kd)Tmn.Gm.]f'S4-XCO >b i@K#>bL!a gme-G(e%-kbhB*SGXF(&bkF4M5[B 2ksLC[]j=BIm_C^n5oMk7>mXr><^?YRqJ-88)nH.lYeBA(TlT.Xsf%bM&i[iAqhD2nk#JkbTS.Bm tnE:?h, HONo<Z.<h2K^2a)Q>E?+(+t'q29[5Gg7D*0"EgODHeaD'[O#SDbpNbO%h#Z6&7*0AW3*9%gZMk8C,_#4R*V5Z!5Aa``/PAcpnIc7)q3NakD44nF6.r\P(rB<cbE0XDEKF=G;ok@o@'+]4q +-[s%"?!t9p`A(/YO'["]$NZ9R6kOZZ0r>!`cQ#$>PE6rn,Q'jq2Z$.t@clQH/q)K@IjIV?Aa%+.qQ^o`6+`NT-Ac./4;LQ!"HJ&@)]4kS-dVEthjcMWCM[?Uj2l5`!(la4LYpAt120S[F,$+i]MY0q[j!bOcpABT<*A"Ge#%>>">l>J!E=#_#pd73b\J&81(+-=b0;ofqW#DAeENO26b=Bte<=Q:LbC/W4L'NOJi*]kC(<1A<.ne;_k2K'(KA!CN5IYW'_f>XmZ3J5E+YHf><U.Ie0TJ'A'9gpT\k79EXXKF8b0ZVM CHlQ%oK2^ZtaOQUMLc&hKAA8A3']1)ZTEOZ<o=W$t1q14YPAlP7>66pe(+W%MeTFtGO2C^kjd;c[td7:f"JErc^WWW9P<GpOJ+8?4&i,+SfH/_G4gqie$fM06`*M;nVL`BQOO=mGet9)$`o/]'eRnbqEgs+ee;b'JNQ1'rRh9F]?,`.?M]s7TbZ.-7X=gI^Jq[V;aDnAa+XZS%+X?sXr BK,.G8`7d<p28WBnU2:ph>8X"EGNb`\P!3@kc`]ThN AYGM_6jlqXqj8RaH`BpnJFO2G;^ _A$Q0Ol#6 m4hSdOQJMfg_"j>o5Z$7gnSf%i:A=s5P`M/6*>oZ72@;0\\O\NI!bo<H>0IG`/1l0FW/<@lnX6#\BVl'nb\s.l4/KP60orniFN!MnRO^2`l'KZHHne*0:lA(Ha<*Lq3,M'>&fo5';oqXZl.tbHU-`O(sJrsD\3KA^,LhM!:=YmKqDRCN^&^:L_#H2SUS+n0[(\SE?qGOYE\CV[7UEIk<i6-*F` :&3X4r!O5&F1#Lb(A ,iOq,bM;= KZm*4\8A+^g,KTNo7LM!.<5FW/IbH/+%m'bq;5@GB""IAA97Jt_VT/K;9EA^t4rt[;0^.88>jR)bPsA=$%P:0jo%B67\S>F'D*Y(onLJi''3pJpDW^$Pd4\e='d[lCfj5m"ncOQ;FIGS+"*#kB#*.@ tW\Z&!rZ/116]lhp23o,2?=qpc"]3#8>$/QXtslaYR2e^A%NGOS6?^h"1-9AS%H[/tUH9NF)0cKjLAl?WT85G:_\%28?)cM#J)@i0ajWF8h#f!%9d68&O2;LHS`G5&8hUra(Edco^\Af_fNcgaoXaLH)b Y9DI[]_8B`=F*8"H&*)hD;]5O<XF'lZRd:;TKHWGK<QEmb fq?t;J#0M32#G:5/%Eq1hD97-%5JN>!DI?]VPR+`VE/.L[QFc._d!kJD;5.;pG^`7\?O(tsh$nn62%X>5h2j B1*\can[?.t5>:OElXG]o]BE2ni.m4GkL,#AM5(=5h'o5P9n sZJ))QU/]T!3ngkVGW2:Y\\=A2A]VQ'$-g]taXA8jY6@8c"He4j4ai [b*5G^>bRXBCo!^f!8c54&.I R!a`b C(<=.`Lhssq:nHF4m8`5BU>Wf(Fq/AnO:BgHbAXd4S@TKWFscj3@(8DA fCt3Ap7Af=]JYGcIC$k[#,%/jE+X8 f7<$!kZpZ'sT53W@@oTiKOi*9Rsr1Y-JI;>BOIqY]S34A:*s-hhkQaL3UCsK7eGVcodIqGB<O*0@*(fgmF@A<)Z2fDN,t82a7aMX ^,o//oZd$Z&ZW9A;r^5`ZVRbd:#t[G@>`P6\(M$9>q$OYtD-_`,lF84SFOAWdEcsW8p1fn6\UUoi(3iXNt[M-7'ZDh*ij_rhO3dr_V*E/3[iGGl:G%9 DdO%+[L):QVF%E9oo6_+j_o=@hg9c;nGt;7pWCA5OSEb)beNGrl7Go*:Ab9/La (Vc,CHTp -ed\QeI-L%^$'Vp]YT"Ce[HsM3"7?T#e,8Gj". e06qYPms`_'mp:AIgealhh1Z7$o5sD[o+^XjmC5-kaX]kGZC,0Lo3S!dg56eJ$*G#U+k=. <3Y149a=1@ _Q8R!DPMU^/Z-WKoDM0@!E5@Ja+&)`I]-H$3-@*_tMdI7;A!Do'78BOZ#9RXOGj0Hhq[#^m4&75kF tr&mo6OD,#G (Db4"\e0hJfAj!I#aecb4UEfl>.a9tA'T&O5X]j]I=ia3HB0158N'.%h"6j6Ip/g,nke$",.('-%UQYjCQ'etA(]lGP!Cr0aFO1GBX\F2;Y<n_-XTO:(bsl$bs2]eT5QZ0k3:cQ0HF.0c.mG0-$L4B6[SQDGaO0n$ed$_9c_"7%E#qms2S3=%BP+AI3rA=Ugt!&%=BlB!Q8rl4(p.W;^ABkk.(+%3Bf!AF_P L1iF<&gFYhbO-0H@Kt$S8KQs(YLVFF]Dpe%ljBO'#oY%Lt<M(0m??4F99Ekc"s.tc=OtYXP"Y+0e381+5=h=e9QG,J(QV2?1`h/>n?j ?DK"]kVYLb%\1XZab0n:7\mt1sHdf.pUOS_)#B+lat?3L:.T."\JbMJ,EPN^2 6d+31P,TJ:\TMRa6)*]lT6iG=B/W9l1)MmQP+oBH<O"KFZeR,sK"gFfCD9&Ae_S>&&"Qcq4Ak+f$jphpbGUc\f[UZ@RXh7[G?O0eGJ AC=[ot6X5ls!ST!+^:`01dKna?8=_V0s#Lro4'bgM52UR1)!ACO4Vf>4'R:r=K-=6Y^j"RFjjL_R ij?@tpa(EQ%n5.B&bCY]];Qr4P;LHZSm2b)M?:0rb!f/C457tRmAq1Sg\=GtkG;saf9Ag[AS*qF:FYp7$rm;;ksPf3Re9egW>eLT_V4L(a<\LAGjmkD1<FX&5DEpmtU59b]1M32#J(:fCoWI&!AfUgghsnTb2m_.G.C68?*,PF#cd#^hO)nA@Wj>(so:)mCI\4QYXoXN9d_8R>+@& tGbj*f,FC>+F`'\Ep`J1Wcj*3N8#nm;c1=qIi<N<!(`%AsA)Y'-NAOhgnpKXB W-3d'RB?\/T?B8Oe :73r&Ac.h g!s8f!7H@)KAN'.@cs01Ac;r#,;l.%t6s@gW!&miGDTWS;OA3GF67]!7!4,;cpZN("8(`[GR*GQTOC(_)tr=j)Adh-W%\'4\LMU\e(W&5$4c'IM<- MUj\;1O=iHcA\9D:Xtd9^a#Ag:[m`deAaHbQ=QdLhAY;tK/J&LW Ld8W+GST@TGhh9c;0,&ks $TObV`+osdDbg_c<>9*#HMbtdk<A*<mEeoV=rb2Q#PtA,ANTN,=:#= Mo5M\;Eq:9lHi>J!q4Q+k?VIQ(NW&nU]DEA&8pMTVq@6Orq;NQ[h6q=)?AEoHTEc<DsXBMqqARD&9O!9EY<7qST[bGk]F@A0&-Z*KWTI4ip@cRr.SW/)A8/'3=K^ZU:EJ1q@.O+p_JCQ+7s\eYra8^CCFs5Ebd+Jas^Ga0H*S"X.:2@XT)8jHT2qP5Q>QN?DYD%F8N=7F75UsA=^DL(* Y:odI+^'3"c`OK.;G`c[8;?c2[9bUmA37!/EEfNIQB*A"1#<sQJ*[a0GBV=FH9VN'tD5?>Y"3_._Y/'Ug&C_`&5V'')6[t.4n\<b+X-a[rH8Ci^:E5a3b XkAjD]&HWWVS-8/.pNM/n+-AMj6=1P>+>[qn #=A66c3'"a?_'R\QjPd\-f?c 1ga%M`^3;c+4RUe+8J]Qc^c,Ea6qR:1N_@#i+BgPD^QC4$@[7'<8Xi8^F\gEH7_,mHW?ef.$QcN6:C/?-W:]`RDCKN`d8GV@@R*k=Eh Pj1@94h%n4D#m<QdD?a5a@ ,Ws#A8G\6AAY4.Asj(l/\<b<NaQ[%F-/%InEjS6E]gVdTLjBEAS:mb?H"$l1XTJ<(d1?L&64B[RAA`>A8Rt0O<(l7;R4(sg)EZH?!/(iS@WX`.fro5+$Bg07]NU^+S7&3Jik'IOK_ZfeGma;rK#$ZF-iPa5+d2LMWJR504_EW'/!&[&so,'GJ]NJLb2kEp'S87"_VCmX<USO8M4!6AQj>sKc8&pDg399c8Zcqo+(^9VV\-4QE'79ir/;2eI#HTb3i8nXX9po&?=i+75Cg$d8QYB"qAB0RUGUdZjq)EC)99>ednIT+rG2P5>/"l<$^#62@X.OP0<\l&t<i/aQAn2-K*bJ"JP1SB\44d,77@<FL85Nt_B8$\B#DQEni@^c_nX^jGZL]4W*WHcacrkEsZ3<0jWE9!JWMA:@4/B+sE_Mj O>K2fqSko[-G5+WXG/4i,lt3m7j*gp-Fqg,2;DQAA17Qs\*:UZgH@MD$7.Yg+jAnA,_E$[ZrA(SbGGRn$P[ Pn[$Ak]Kf1tm&e"7\3ZgYWh+Dp4r<`'ha;]^34 ^PTd8$Fd[_r#L*tL2S(O/TG34Te\7Kh%WSk`CocYt@2tI<ZU^"0 [J`;l!g;B9"jAtnG6gqjSh89#2Y^!DA8(lgp+EboS8!Q%)UHU)BW+!XniJb_gjI7jZnqj>&0YIVoa@#:@iq#5"gL79n$[Y7Esp?b-3Z+QjrVJ1i<LG]*UenM8`='sdi9B!)+^Zkbb,(R.+!H31&=XQ[/X[)oF2?GrLV\hl!`?Ack@P0fp=kL3o[g]__F-]<8Mp(2'f&YpA#9S3\ibKX"9W.,&RM@'k53k/I[M;?T1<^2E\K4tkf.:LE=*,0>B&m5p[nZO&j\7BHo@k(,;`>b@A]b)Y:*C*%g/ab=IG/^&W`7eG?"X>\"D':(p2`D>QANkSke_V6MeJ3X4&gB,fes+mGORj3NApg34f0\+L:%JPm\PA=;Gbh^D\;[RM9rV/!pB$qNAA9sno2"bCM\QRA.MZc4&Q`?^OVQ 9'DLP-S,'U3la.pjBK1\g5Z)i>)S33M& T52iAlVo0`A76jFEimi&aafI7>pOU8]_SroKVeW. ,lM]!(:Zf1=V2%@/"ZPF:XF8TXDtAC'&rc<GitAK!RO@EM33MoBTP3G%7U9Mab@8.ZF@1/9(&S,!8q1at=5*C2&57I?phjEH scF`K/(=2raBP`AK,!0%BlY1d0L$W)+mc+6,OtL?(t&qr)pLS9b]9ECFm!KZS(V*oJo:g8_X-rhI[p.A$OT$#D]\PC6G<44 +5<rdIKBI(.d_M8/`;3,m0.!V*,q+WqU8pBL,>%9T':;oLIa<&P(D$MF8KDsKMAGig]UmRaIbOn<YbsU=Di9XooN02J'B#YW/BU[J9%WD]X#8R"a#%Ffon0$9<a)QBid@:t0_Pd.EON7:i"'/%pEf#AKsrZa"F[De,F[#fSZacHt3BZj]))[jm%coClL*)lTOGrD)@>P?9.Yid]s6::3`e4[H*l0Eg)\At:J#o38<4!>Jb2/QQN<H2`Fgh65@1n<E5=?[e(P4"qIhU)C!JS$a(1qN9q2TYBkh(a2B[)15mFb)Y#dN^B[.^tZ(+XIBiCqOaf"k^hfCdt*[%O$HU+9*l+mG@a]TDBHWVZIb.HE%:KCUkgf;0,#WH+-E2ljPK85OPnd!<25`AK?5[p>E*^9An:I%-bm,)Ar'i?0,So/k-G)S_(M)sh></2S(%ra7cA!&,Y6_n-N:56nsW#Hq5V[9*BXWGM2qr3QR;W>TqJH:_2T9n^P\A>g)[Q:`L 9X4[k.#X424]_oHPg.faGtb,"!s8\ PqGBae+V9R42d9qQ$#GC?>fTUd8KG!VIAiV$MWr$aMAf>,e<2jfgkB=i@\;CD$Oro^2B=FN M^o+ n8@07?E!`ebB^@BWN1?IR];O_f(sPdLnd]6n;5"7?n>2I[N2L?69OH.>.iZq6&`;^iTaCK !?Ai@S.1%n(A2\$;/fJ!6P0[YL8XT0@:Q:i]C*9E[-S,t=Jqchq:UW[AKFq%A6I1R(F0,'DT3UZe5PbG*?FHaRoBd[MNja0sN@4@X2_T_Sd.^> 8Z]A(dD>(5K54HM5@h"CK:`F/4='/0+bgQKc >Vq]Ff.HK*Xm`Lg+`L7mk%1"32so5Nq2j6W8d%.QnNZP`t5eV, U3Jln$]5^5]^O4lT8@SgbpS"F)7'p?SYAjBSR Q`opb$BV`:"3bt>WM%_CT'(Ap3P>i_ C$rbf47bdK760,a3\&EdC_]d?:\Na$)_5XF;B:_ENnF&Ltd"XEF[&0JfAsID)k!?*21!rI&:Cp?/tkUh>:&:C6KAFqCRQe3h;nNtD$kAqj>4kJ#s@L'YCp-mRRZ[R^p^Z,BUq=6=`9+!)&5AoJEg*rWK]nnb@)'"/S)CsYO-<Aj-pAC+LR>X@5?dq.MF[PWEU5pt5F[]W[M#rZ\Isa%#;KeQ=4t[r%K)mh6b1o04L]N8jlEB-*F8gn5o$TcJ>T#%;1Q',oiXOQIi0Z_lm,Dh]&0e6+I3Qeb9O[YEX)VB*K\_1_t'N;nNc*$I_7'0l-_if0pYIRimXPt?ZGZIs<\>Vl4t]F!X4E&(rEEV<I'1!+9: S$Mg:/*p^'SN,W4_'-mm+F9b[pEa$Di1&jU/,n&I:H`\6"=!Fit"f+W^Z%s:b3-2D5,]aeD5%[a.=F50nZb^Rn$>o6Wp[Ei^=+r*q)(lWCFrUk 40p(TP#ATs//KMZLGDmD3G9nF]A>_E+*bfHq<nB]hO$KUAYS6%B-I:_]CN1PPN );>A.A_-X')92n<S]d^QJk4Wp7 0?YWF%382[T5>DI?cj^nTCXE+J]Jo\"$=Q`l-,.blk58Q3N<$X?RQdA5B6=B8pEDR6:KH,ppA=jJa+K@n6^bn$'$O/)Y>J?c$$I-d,#3j^]j80Wt41MWs\?WJE,;COD?4ms,oD.sIRQ9a\!i8t961pg^r4kF)6VXh%&Hl9b)q6K;`hc#H8^n2 )AkTmRhAMi3I"RWbVkaFcN=+%5FYH[*>XUn0/b8XsF!+f^5/0ZfClKWRFbo)M5tjDPecUD2m=''7eSmM/[mLm!r[f?JmZcrkg!Lh[1dUfN?dA@)F.J-9M)3$.Y20n8Zg`3!(UGd<GFWZ,OLk3V2A1'We#bKF&(.#]1H@&LS8c/[_#&paml4E7bisULq`>(MW(!#5ZTk2.M"2cSaNAOAUktY' nW2%P$'I>U\FeZ [N"$%gr1Uh=[6AGTHBICP3:\*l#_Y0k"Z+i)W#8i_:O a9$IBpl>:i(VYHQb=`r"6 _fW:gmJ[^6*`E9<gJ-2_6B#Zp_p.DK]LC%0K3col2g3_FWKZ9/R ge&+EMk </5p>21NAIAZO^#7'9Vb?oI&.\S7c%#^#opo9IXehk=\0$T0,G%e9#82k=g$S&G%6N#^S@rDA!+rrf1"bRe%AL (FOT^tDX"( `1?C:Ip4sIW(W%[>5Jh\UWaBn>X<mJt+@8EgG_lIbM+)O@NoiR)FB\fX=XC3_G FPq3:ECsU# 9on?r'd59J'^/>."Kn[=A.c7#a"C)<:kfN" 9JLLN_S@aRHtdj<[DVF"f*9?)do<>pD;1kP>]0Vi..`S`,5.>9fq^pL]A0`k3Vs6,]857=RYbq@!UHV7#9\,F6f[O8Rh5,X8b!*h[.&6o?BmZ#9/Z)=[Ff"EK@J`p.i7?7s%BA+n6$I\-VL0agqa7[42#t)+a<lkcQ,']@$RIUdcnnW%"l1oU3<4gNki&^=).I@U@3[aWLTn`'QA<_4$3VV\?9Za5kO_/U_>`/-F(Rs,.6$+6As/EQAETU`7_`*NQJaYlW38t<[FGQ,\S2*q!7mZ]E3a2[gBgS.p=<s2JStK"Aro<,?UZqPR$-1EOp_b.,kgN9:0qI$RfC)f]rJr]lPr`WZ,/IZYSCM,gTQIJHE8GX+[UUMLf_@FA=HEQ5W&>`(O20#3ZfCMTjW);J;1_>6$@ZdU &m[HUg>Q<tgQ_!)k_QE`[%.ZUB9]k>^^db"&rlbj?KDiifhg/ZZ_APqgXga]<I?-DH!WC33EhBEm:UqNh_a 9 3YZR`nlt3FRqXKC@5e-T8E)NmP/H)gSL%bdT^Ar6Wdlqbm,1;"d]hL]>(?jl%0\"OeGm?l*& ",ptA&]q;N[%KIrr&p_YC/BpJt>aANfsB" <=<80jfO3+pc`%iQ[G?YO6eP+]>d?nq"5,^/b+ZacXQa#(/!&"bCEbSqpD'3WPdblq$F-AJi5)2(B3>5`jF[9LDU@hh6=q_?L`R9H3&:TSj,hfhNA*J&%d2[eWol4`ZW^)Y0^!M8UM)Fcq<;610>oIQ6/7GKALd+o.:$:3kqk)Mot^Ne0654ciIqn%h+O@\$V9D+tt.B pB!1fVL;MUGE`s;(<\*ZK3'.?WPO;jH9K[/G&>P$8Z#-&E_i1Q(^(>e+;[-g0PD&.AIlFo?\RFs!T*Z?#W<d2h]oN@:2`R>7aB/.+4oOgQd@].*bW:=T.qJ3\j#%5^!N^a `[!tV*dojYTeUId.kI>%?8Q&5Gp#IL'^Tsct/5E\imT>p*oJL KO#5Dr>1.1mRS2eKJ_rZ2_cS+c>rs;kE3a<[K3[T*-%R^`@*W1e<i?XfV#qp'#7 <5n1(M8Fhh>L9&_&l#=3NW`+Y^]KVcg]ZqYG,l2Z,j.7,[02J^J]!oeoG-5:U23"5Od,da430\ZNXIHd.rJ*;jUt9d>(t*L^GPkX]ce Ya#NC7c#MGa)!7cN)j5LF%&X0?D@Jn%*/A"NAV$G#mI-+mj)#/^ecY`^!WKfRk[)Krjj1ARmUip]/P#qG4I9H!<]*fVBJ)k*dr3,gI*\'M_bb4C8`ip<-G_<?3qSr00rZ`%W`fA*7Nqg6m`". t] g2mdFdW]WAc9)4=#U/P>ngYq,YmqEj,$oYIi\#NF(>ZsEZ"JWrfdhTGDVP6tSH?`Z";]:gMo_QQYXA7I4Qg?Z#tE>?_t)*t](SE;r;J8cS3EP7.@3p'VJW<A)kt` t5"(Kq(5$9cM9(?7cZIbID&b=F%"\"=?E5&%5$i)AKY1&3IY3cQ@:\!:'BsHm)f`=W]7A(F+^glU afRa5_Q<KWr153#1Q[&B9g`J;O'7"?MJd-7]`)M/8$QBh\;e237ma/4!D9aN:FJL;SKAWAkDIt2IN!5'TFKVm?C_SA="(>gD(9.).N'LTH5eA(sfaM8)K'8QK2Y8*pNK9KN!%"6'@ho>PL,fHsD%eim[CThlG&SH>eTd-BUo]MC?D=gptat:;":Q(X;YG*5rU7Z<K*kAUA=/oY/qE%?ft`LdHnI-j// =(aqk\[K^ohBsC`$%LEs==T$M `F\]U[5WQVMA3oGd[p8l]AJ`m?-IoSR&JU\c\!&?,##nrQB:>HN&[9[!)eRGqnV#8A44nOnh(0Q#+G))c-nQl1Wm/]t4bfpO&A(p)H_8@!A_!rP+0#(8NNa\53QCFI<tk+AQG-.=cJ-#5RcTP>!Irc\#NmmKX;AX:haa'Xl)haG'N+(A@hWfd'QR(Xql,mX!#OA.-?k&Zl)HK5Lmf6&Kp!!d<Y\8W<][Q 2.K&b(7`4nmjl5ELj#PiZja&G-`!fXQ2q<VKb97D44;7i1bTe^JcPJ#;Yn[E>S[fh:rabYhCSl#c#B'F4ZZ-UZ\$5XJDf_X74K]nr>T+"jem!+*`s[Pq'$C$oc'/r=h,'6!O*=3.1m3.SPF4D]jS(X0#&@ZCo)[GG_?`oddGD 7s/7[bL2 fN#KQ:7i:B5(2q$;s=n#^1"c$,5G^6$`V!H?!I%/M.t5n;;?%rph(p0YP/[heg5E,:o3toP@=.OPOPUSnd%RH=7k[O&Pl6c&kYdi^%Yj?<BgZIA@34tffA;lIZ"1(r#Jo4`KG<nIp#A@^/9j)c7(?:@BOJNeI!&E=>"FEl-A>?0isP3KJ*=k$--I5Rr:EOJWo>1bA:n#($pV_7VoIs)GR2[p>C2C\p5A0X]o J?QjNBb$qIeSQL=@62^#QhfA*aYA%f'$XRl5l9gh_G,LRb7a7O1Zg_;r&A$tA\PK&B8sASCYObeOA=(FACKH3!`[DHfpf1\JQnEb_aOk@UbO%?'3-WfSV?b)DIcVD^I;eAU#9`ZH(rp!i.rf0tKF[aO9<,A8#or;^g50XfIG5;t:3<)i"gG9)7CQ5;7MLf>)nr9EY@kSD!Uis*c0/^Y[aIYBlKoX#sQTP4p2+]$ZA1;ZmF%b.aUTSi<"*+@A?G.\6d:EX2%=1PfD'oeF!UtZ^KJ"3JnSh]"s^8M4* ARL^S+oi.Z5-$j`6]%?H"gr;YNAr)-rNT!E6MgGkVN>8`9e#$ c#/`"FR02ME,e2)ber_C8^$#USH:EaV )pi;h=oT aW";R&&9B Q]P@K:!1(A&"G?]L4_c-j3lFVCCqRJo*<$3$!R56l<^*C;)1GBl.">LC2QnRi"AU.,%2o;E9>F.TW4rCOfo/.iH_\Fk'T9b3bR=T06("Y=C>A%7JNc(`.G":j!GCto[<hfC]9E!NOA@<GN1\fWZb[-o5W#!>aZnDR2LTk1C/,A$%Qna7/lFEjJ-dHFf6c3`2OQkYBi"9m"YZf+<l"qPc8%X0=#8ZIOkEN_EA-t\Z$)3bCh,A;eqX%i&0[iWm$n6Gpi&?]XPXZrMl14%H3+R"i#4Jea]3_dQ3 B1jsIVR(AR"r_r*T%l.b?%++-G4O5B%oGDg6 T/Vij GYeR,'#q3OgANWVsVdXRo'2Vqq!"(T3U>,Y%.&o*;H<*=r0- UT^ gp^c8J,5cgsUKleXTH^l?kDPC1 =*l,qpe@n>0enhaI!4A?OR6jb.ja:/ qrO(T;_9iTMME!F/]rOD0`%V.]BpcQfk]Po:)0kN;)d%.W>GCY/gjb,#Ce7'mCOW2FKb3Ea4ZJei%:a@^T`p>D9Q(;I?U;F7(Q!eV.$(O>l_q#olXJ!=B3m_N;0QB4^<nBB%N']-0si5Y[<U5:nKi8/BmThY,q/2!FE3hAA&_F^'101\sILD*ogY]CoKW]N*8j52&!F9'QEg@h[ d^\r*(rOm%+];!#)Y996'*PW3tq[A.:%=r705f?6a(Uj<prOQtaSNINUIK,7(;nXIp9c$g@(ID,N9THl6A[Sf!QXI6nF2A"ol3?5Z-X-8j/3gcm<mbPr3Q0Y&_R;j`XdNtL1Fj2l5mlcS6rf(IV=/dS?\\(fgoEfL&(9Y#*<F $K>pjrmRp-4.#=#)Xm382Yi&8jA[-a!(S2Mi6VZ+>Q lFe ^h6P)_N+0nsbb9Yk7R+FI(WZE8\nN-.eT;105'(^QCe<b_"eSJ^es-BDt@O!S"QR#o"NPm^&nM<: SpI.=ksN300qBAUQCV!Yqbcs8AJ%C\(dN\YEI8,h0OX` ,#:T#flVIA';T.I+cCrOb7IN8;LHLkH`)ri:t7WR>_E$J4e\/8ThAI:CU`R'&>HPL/pt(n"Qd\A.5G3r_>th%lS_^sk6H].jfmTNpsJ=",8$"TStbUY#&8Gc-q,Xh<gse$deq<a]F6FMYG2g6W`_oD9-%Ne;0VnpJaM\f-/obn`34jB1&Rd5sbl`6<:D[.A0[DStLA=[F9.;+ 7,48i!56#br/X'eOE3^)cJp$0#qWI36pjUq\Rm+Lq,P_H*[4Fg7lb_(8VYlaIn!Sf$/VBg(WFALPf=#,PpMT3< i2af/k]$=%[/W1#(dh+/Oj'PQjAU!4H*:KO1_Z\?;QL;'N4 "k-Ee>4]h.p4YZZ@>hm8^_tZ[@AK_h$Xn>47//PMT@Y!EO=m49=?CO_;(2+nS`3AgXf&][c_"$N&BUpnj+SFhTQ1a<dhW Y_NaA+CH ZWoE%e-%'3Vl!rZ"#_g>CXsZt&WFpNl66A&2V-Qt(&&""=IfljF@"'&]Peg$ik5L%TKo)_^7m=H37bb2(pOX-APf_IlRmiAE#c8*Z4MI.bJ1:``C@pSH):W8Cdo<o\co+>SE#mbo9G5c5"b!VC9IZ\6GqgGtAAlS#S#U6"kE@+$`P3YC$n>J52S5t5P\*Vt=Woj.->>WOg`d8:iidhR\F`Th[l?;m<,OAag'DY_DmXi-asq^VA6RW=lpHj*"3;J_dN:(AZ>CB<a*WrK"bUc$=EE@^/7k+o+L+.'jffPTD4B5e"^+Nb#tr:\Uj?a4(S&?O=l/lK$`%Hq`7cNh*7Pf;g]5.78]P_MN`PfVk'KWUL%HSgp@(Z^@#;nlJMXpSD56I^c0'V!+Mdi,pmK]L'D[orM<s,bTB.aEia>gWC&2tqrf]/*jl%:Y&MtK@?>\Saf.>:cmp(-\n9K>#5DCA$!_+k4kJN'Th]3Qq!dU2Wd!=QlT&n@^eBd#$`/rgc1`IYFjP1KAh7!RG2-%I\t"ECc`n6t5`sCgjHk/rMA5])U\7hMGh<(UAc0RP1M*VaqH9A;2XY.s^s8-KeAH#ipk+5@U*DF4`#+h"*,>3`6[cWB?cGR-TehldI1#E^88TCKd\m7&IQ=?!Tb;DM_$RI/&8;Sc%m: V4o;3[48$>5d0R\Wem;+US0E)+`G<2=]Zb*L$`W0[^dN^N1jQAWEcA$)L1sM 4YIaGB>9<s6n'rUAE=kM?OEof]"ng9Dt7m-b9LbR;Wj*a=^-Z]Z2OB\Uq)qS0%AUeJ,(?aK6i1$"RdFh61VO5*ZX/0,Js(jo'&ITRgP7nl/6>,e+4m4C1_[g5[s-S_5#L2f-ZkCFE@J"l?s1(&*":A-X'Ki@B*Z?AFdY5jlk5OaT,I^aTQd^V]iH2P9GY":ph=P4oLi-)3P&[LS3"cA.85a Vfbl5VA`#[(UDKh[fn8+MkV&B?]`6D3o#JZLa9Sfh0kp%Z6>$MMN.!ARk$Q3og AXd"CNCM)&)669T76A'*lB&A".N#Y0gsJ A3sc #/cL"&a[dC;S9$.C8R\[Tg`Rk)nmt @AD6>sk5+6-8V=]F"Y5`Z-^L>(2Q0_ pcig6GKqho0/5dZG>6.U__ S6,!L) sp8eYZ;<Dd#SYY\mmYt1BHO7-B=q>F`K7GK-]ViPKqkIrhM.AT%3H%eH 'mqa<lgTX Xii$IC"#_@t*KGro(4j;9"V.`tPX%3"#gt/73ta]@>4bh>\.3P)Cis(/;W<%LVXeQlQ5lO'31IB_&Ue0`<AdoC&s<bhdA4$^;-4WD8.=RCBq%OQ%p[d64UT^^9`9.ZYg Ak.\8oR6Sba!rLVn3'C@/AHHE90#GsphJ9Prh$8.%21jTjhN&l\#8G[!.3C4 ]d4J^PTVJMm4bpl*3PCkskAktVO1(8&!h>#KA;A*1oGdKf268<lLEFP"9K<!CA\qo 50!FH[;MPjtiG^N>licsVtcpU,5<#jnr*O`Yl_fTA<gX+?SqA\1<^"&9mb;q?$fn/tS#@<9nPp#b3;=]OGb=Set9!&A/,e1?C7&XNr4Od,OAV_;mRNEAgcjr(00X]p*n19:@inqWO3Z:3Oa#_+l0I@`J$br@?6E^]m'!$Fm^BF=CDlnc>aMrlPDU ;d JH4g1]Hqan Y*"qWsiA[0&h+6EY .D]4&<d$ t5-T:-@/Y6!A]7;@_#k-%]A`VO`h1gDR A!i>e#eCRCSsC8Yg?gRP9rhdg:@g.H!X2Ab RNKBsQ=>mde.t3)7&m#DbLG]qkm1Gr_tAc["br-7-,3#r];%W$ 3m>>K%JgT;,!@t`IH?]R9]CEq*k)At7Q9<@nKbX[8m!:OB)BWP#<_AAO89sON[g=LMBk3](F]A8\RYt[VmMs#,iQ[)eC6JA8r""")gW?Jq#5!AJf7nAa)R,3e2Q?cA`nFp"M^)kO[))qS6lq#%<8%%,N7A`#Lk= >kAaE``=S,r"EQN\3JMMR)bF/8!Wf.O%A'MqIg>EC$s`6%: >3]pHd[`hZ ,,j#dH1>OWPkL6'^HNb).YhY16B5&s:!k_,"&%A:!ZRpNfHVTO3q<\QNAt](F%K,B03a,MYh`k<ba]7R.,pOCE-_j.Y].?Sg%L#m_q3*(AC\rU$!1:CoYgAcF96VFGlK$:Vpn^mC0'Fj\/'HY6-@,8Z[c=p$dsqd6l2\Rj;3cbM$5][jhgrTQ,e90d_)l"EA[`5r1P#AXjeanD\%\&he1e!J&iii?Eh8'FoZ6[djVAi&P+c_4RZN"'SoH6&kb>^jreYh&?NCqF_H8\99 tWpjJJZQVqS?p.!-:NrIC7*[7g`dqa.M[W6i<c,VaV)Q 8'[>#8`I80ie6GGY+FWfAp6Oep^\=#=B#.rA8:X/=d` rP)t43i,s^bKkPBS4G?_Z]Vhb=HA)+7E0M ^V,&^`c'M&kS(r6b#ft(F*@rYg5Zb%4.gih[+,r '_V)d07/8(d7Algo)GEhW>.g#jhJ\`C\Z,Hn7k(41`o:. `9 pHBRGA0q/%<_+43<Q*U?Dj$:tMX)Y3SJ-U^\X- R[^_0H2hIR/T;-%@2PtM]c\??A1D^F&#`H'&*00MjMX>_2)lB9gjFH+OLjVa&:GrqR"$_'m0/GYKA`FPio<Z-#+1qf1/2YLSUW.:L<+ti7k^j(tVY131(Yf !Vm.&^rl"=OR-`hA-jlogkW]M.k?U<d_I@IXeR[c>D-2KlH`fk"Zh,@sOG30,e]#k\4a)47S:%)lhNd2-Olmb,r)hWDW^pq6t3](2('jj8V0oDRe)-r/[mfAHol)'>"R/5U"5;5lW>1RDc5TB7`gR<(%jmgVCl+.dLpmsb-t  I^&@.lA(99NA=eL'j[ZS5iQ7(27&-JjCTlHt&<4r;OorA+Qr/1-3=jc'g.*$`Ap>3)O'_M"h6Q2?ghgsPrJXRbA8T._&_)04!0k`ls3/]AH)Iq>s&aGK7fU55GEQLD$J9'W3'.`i2=]F7q)8e<UP`RDGKG>tEl!B+M5_Yo1bN-B6$79"0KM]CsnY6;cqeiHNdO.9J"BI[;MCo>R!rDX7T;*9[_ \s&=*p7e7>4L'L>knbW(n9K 45(T_<mYo`7FDa&cSJ.:\o<&%^t@OtRqnY^lKUEE\_]BSZQL_4;Gb^#C>G[$_4k3Y^8Yof)550FJ9,^6 #AXiQ/tekn]OA3Q_IG\;nbP^-@!EQP6n!h]`-AV*6Z8kUQ!<fBR-T"csCmN,b;8O/mpeIN-l.AaQ[Tc9X^.i;$If4_FV.) ``9,lNI\Mj omK.YB#j D2SjfaaW`?TKi+CY0dOpn^##5oW3O=YN')QI-cBXb-5EO+Y.^,;9nr2n+;or lepUg0'-Io+N*$1^[saO$<<n]Yo13^k`j+/UZ_gorfHm!tAmWiO(<]OcSQ1.$:F`bF&A8;4@MFKJe>g&dL"\@C&EP cN/>O<ElY c`Uk Zj4G]5b?+KZZr*m* Zl.pd= MS3JH!rOC%E(JG1DS$U&'YWbGn!^CL$SAd51KF(kL'ojFXsM%Ck=AGIA5J5>B#A<J7=\Oob*n38>dfA["=OW]s::[WLCfiRqa(9;ldB[REY^Ep#//28eMZ4<W%Df*q*D5AM*-*Bc"9?fN67E<P"en76$U,,!fhW;<-;?UV"$Z(H?1m-n]Q\?dB61'\+lKA]TCZ9H:5pQ-6=Q$G4729/#!n[s<!oUB@0Tcra$e.Db@dAFh2Sg$3'Zlbmr_oC"o?]>Q<L6[m#o[[HDXS>T%'6ZfDBlE[KP.^V3ljM3A%=?,>+/-P83Mik2hsGoB.a 4dne AeO7i-mqXo g"LQb)4!G_ [e">4Rg[Yi('P*Km3K\_=1(4IinfR:<Y6adAG eir?6UOAd'Be_bM6""?H;QAN]Y6leN`6TX(I3f$::F/ra@fAjpA63Yc %2\3rJS8b;qsC@]c)UT'd!A:Ak!'\i*P1 25WDDb'D)b^:so`E4l=?8F"lpb2nAp+\eDT21''$m\&l#h\g+%"<dO'#.aVE>R0lr8lfk=94PLDH.IoSBf,;]#nK"3kb?Z6RY\s],LZi_"Sd@NAI_$GHNBECT-grSAOcL@WX1,'FDeT2XL8OK;d-,L)lP,3\ngKVG[Riea`tK2rist,D&OfRZFD#p9]8CqpYIPq*n)pUEMW- FEpiW;_(< <6To3Jb?RdV(@1j?r.$#2^>U)#AT]+t?=FcB/aO1h',8peaN!_qE'CM;aLTPF(<!_[8;'07l_`OI1?g,^]fb=;<k6KBS0f(.6e)<l3aR>pF"b'`kk[*G@%bJNKU<a]Ij([HC'lI<h\JcMPARB* JC>)=]#?FpeV#28^Ffb,1+mY6<8J4+=$M'!7 =_"1PP12";)Zt*MT!V#B7coB0lRHT]rLXEY+3t"-oq%`gV)1IEs7F?Y,67h%8@6,[H"ihY9+5:sHTNc/qo-esI"_nrmHUZ7Y$!Gi*k[.TFrKaagJ#.ZYc`IZDb@S;$R`T([%\otr(7'-!-8_P/?#1qX4e<^==3L3codji\,sAA\)"NR^]KX38CDA_ZRk9g/*Rgd'dIU'T:UREr*9C]bR^"e)&Y6nC(fr]"=0?QX:6ldPb8)\o\Hm7b`:k_PNBYO(itiV"o./S.s\Q0g<I;qQ>(!@%qKX:32LDk^S(t:MBCXA<j Pn'4tpQbgBeOX(V5?'WgC,7#Thr-n K1VU<VKjE,23!,G2tG0'?.c"#],,K'-9AgQ>6NN1<q%ViZMW\OAk;aF.egS6Y+(g1at!Z[?N.IlpD6"BG.!J'7?;l3>AsNU7_-)@(He/,ltg[<=IUe6,KP$1APhQDl*O&lpe@2At-@SYUb0%WYt6-,Hg!)>DV3BDO:9I()T/t. dja7JL;Zl3@ )K7@*esQl?.:8Mq"YW@DisKkf@T:jA+<\AaFYJm>1d%;m:('"A0aP`C?>D7 eN>JIfTEIAS1Q@B4kRn<Bc9h?'+#jYqrEWN+n[.?f0%cVj<WmFD?\!EC#[;6$  $h)H0WGIS=/j8r,LP1tY<2ns' GtS=GOG)8mBnXFbFbVn>\/`4JId3a&'^,\n0XGE*Zonfp$1?rO3LT3Xol:O`46kib+<\F,ilohHRS1?<X")J'<IhYe'ZH:\e;C]m`Mpn65`r8Xs=tj@;<b9a$c!0c]<^_MQfZi''P,M=50C:Ac*#s=5p3mga^t=nK':YT=rAacMX50lD2S*56F;[: _agqTtBLO?&D AH0/]S4O%E,jjpMKkObY.82n:PqAD[9+1UUkmA\;HZ>ElmM(#eNE(!'Ip;L3O"t'lr[VhZQkcDO\5*,0d]1PD/( <I#:X8K:;9^m_[jU_EBFF$;<lCN@PCl*S\Kll06=FajDN0PgBT6MDqLoHQ_SC^:A(VAK6;*EQ)5^8oHk\A!0%K3SmDf_##tRS^c"t.3J-nV.&]lcC/=Icq,7&/p52G]idg2/s@[O9##!X'F^dmJ^Y@DF5>mf bcoCVi2chgQ^I%J1Qa3I+[#k&b;Rd?PUo$Nj_:*[`pPNtob%3Xt!Vm],\`G<V`]QiS<!l_a%AQ?"5D9UaVZ><"[AAYl0n$k>dQ[o-SNbQ<qTEND[<a%4O[?J/G_!^0[VPXW 5Xt.QDD/UG=NOsr?`q[?4.)QT9K'J^ipt=ek!g-9>'ZU,<-T"<B])n:GE4I$!4rRGAm8V<.XQUsiHK $aYTl0@1W@5<a% !pa> Y8Zp15qL@=Ao[NY2M;rAJYMn)X8p;c7o6*ilL(`mXG:aH3KO oh1=t_*QZ8?L6Mrs^+U9h%O:b^WlA9QiiRi'nZipZ._VbMVI$4rBg(R5pG!DD$bn=2:!*HVUHE(4!TDZO(A$*knR\hoWjk8Gojroa..Sb]Md;t>Ri49_f%8q6(p0i1+7//+5<KJmp)80\_m[M.qmCl_st06T0YKfldg$4N =/ MQKIhpmN[\oqOdb[L$A#m6_^H^bC'+t;`cZ,QRm\L48e1KgoZO,i/O3i9$)];(;=8r.q;i_?PTmK+A!Zq J8%fdh8(m]L*6?2jT8j<%!O[("MA3hX=Fl>P0Y+lso[="9V?)#\'mBrihJ9`0NG[*'KjpP(<ApQPWZpcG>*Q9ofL^e3h*kb,B5YJ'M$#^P>&Y135]ci3aD"d&9P,"%5"_YUXpO"F83JU))9PJk=?tp(f0.AO7SO$K>B4AIa8IqNl'OYbY"jA;[7n%Gag_9W+egY.f8(k.h)q%LB@G$:#C1FA2XM0>TkgG$kF5[gPD#m&`je4[-'8PrCC"VL!)sf;7E5Kbh)r,&kJHlgEAS\-`bqlN]0Ya#ka2*Mi;K+@EArBZUIp.E>NBh(j`U<+-ntk>t-QmF`Y,jA*I__nA._k/S"U[ql^[Ctc>e=Rs:/oE7/i(6A8^c[i6'\tlQ.q[#DoBe[<BS(GRMR8(f)LTWWh9pAD`R+Mi80C2?APkYH"nA_1^+osK\_brdlsdSbEetG0E5$Irk(:m#r_7Eb&'e\l$TJ/lAh%a7(;h`=rHol<5aqhl:E,jHcpPoY9sE$\,?A%! e>ZHk$ Vf1W5e?g2f\6bK*SSYEZboDaLqNrBB8nX(sIU+*Ca+!K:&/f1_`Ym9rMWU.e,r/gpt;_4Pb!\tIW"m)f=T>UrS2+ErcW=!#LbbR3h<Cb(`3n(fOSX2!jTA!i9\K1K)AV]12k!!Hn2@8FoqfBK0)5kisTAbMb:P"^HogtX\4q!OeF^!G,c;boDYB/7$#cXUV,+0W*GjL[3o\#(:a?H'BqipVm1-sDj$=d>niPS#J>3i61;qWL.aVmT!a_qA:%LZNW7(]=F^p^D$$cELa&_e:AACH0D/b'BMaat?hrA+9tsc)66"5OsRr(ckAUFL=TgA_4Da")KA0@)1gp#c1d.P4-n*ng*.XG1f.=\-;(f]\s"sE#sfSX!gY,?]sAjAOs^V_&b4c^?i=?iDjp7p%^[O+jC$Nb@l9CstnbkrQAb?'tRRE!KJ?+TtQ26[&eU3KW(L7`L)O>8E-)GN4H6/X;Pg7A7j,$]&[?KLq1* o[o'mI<maVTI==r72C MRP./A-5V=0mV`^0+e;.h-&JPGLn&gch0'#@-?OKl[p[8G]8LRrOTC-+dA%3LenE$iss(cg?/[L*nH$A97h"WSt<an!'ZceZQ-ZB=bFs)KTFSCA^Mt^I88`i3hA<7L<!e@jfOZY`?nMO;D70[A=ngLid*=&UXO71R8<(81l.Z:Qkh0.RAf\+Tj4j2aEDJg?>\iP_m?ECe=AMh)Vd%?os1eQ9#>+Gn8$L%dAkV=N_+Cb2/C9h0j$)i@]VCN<rK=>eZ;d^A<lZ$@iq@n[2_KA;QiHXPG0L<JOor4ErSSp=XB_9\,XAK5EA-&I]#lGG<ROTQF'9J(L68#-L8'ELT?C_D2dEd_t-b"Js&9-%m2=85% 7N;AmZh]aip9CC;`bM^N75Xr'$e)+DG(,\%>,Q7:Z.?]#DV6q1SsmMT$pqN""p#`5HjbIH2^((E*dOp\UFAZVKkd2S?FM=n&[nHMJ]S2*aA%WFE7(e"tQ!0T()5T]?F[RQ\R?S[Ms8*-G<iaJA"UDtom+[I^K9p\9snIUt(PA[["d3DbTE4@3)7amp,$,W`Pl?A1]Sh':`%;BR+@bK>[fP!_J<6MbE&cY=$;1src9GdkKiJ+ZlR3m?M(;Fe:<_D`.;I HI !25$:BS-I<^1SPj)!NEmJccU1`0 >o-S!b7hZc+C(.=k(LI66g-"WP>Kpn^p`EY)T^HB?nA[UW[HM<RXbY2;"kK-9gH[_MbEW_ET;R!M"?U"p!.+[/c'e FDZ@is+!2tF%[p3igUjIqIh.#RiPns_JhaIE=Ei(T^OPad#52d 7*^8[8kZT MZVc7C'tl8jA=\.&8VQ;&[;n(8*2LDD$#P/YbPde;c3<sB1>D6&,qcNb;($:gJmLcLa;mR17pA0,I1lBj;sB4U>?t>'_sA 2<7&`HACF9IMJ?HlSCGbng-J[$dG+&ntD26WAINnS$ A]_Eo&;AJdci;W?kUBK JbHDU2=G5Ef#hnf1aTo\AsqX0nBCH'iF)sX*->7G?;;FSkT%]^U\is?>BNWMXGh\in!Ld=b0g6OS,41jpN93[OQa,1.*kNNV<H.sHba/A$1Pl^nr)9d42AO3AU#^V*5A5EJ1Cia$gp^DnSGt%=B[=en?!q\i&A6eiad`V>Yc`IMI?gX_3YZ;ZfF@+o>a^JZn+W6P;UN0U<.WdE4)=s.m6_%4fQD&t9@Q)9>F"O)3*oS An?632I[`68Gm$rdPAKMtHb:dU)R2DX#mmVB3GYt71=dDX.D,kLOnNd"EC9mP%S<fD#&5"$'r]5O"3c#bRaIGDtd%lb Lj?`fIQjJ,e+q\>9Ln0IA&)MMa C@1.a+:"J)A=>LimCYW(1t+9,4h\./VSQHRJt7f4UJFn:HY7bef%/5=-n=;=Ek$o[Q( .:-a,fQG5TE'dntYs7hClXj!)CQ20gEE,3B4^hFrCOL$;id=;lml.kg-]dX0[ZiJ?mZISK"L#H=4T^osPQU(P/T.AA/Nq=oh4%n:m#mK<t%):7?>M!D;QsN+1?+E^>iC(5$9-K?;J%^E3m.UIL6WZ>i[bY-sDtO+6_BDXm1tZ@%c<`&b,g 5XVjH+AdPTWB"+sp#^=hX^'NnQ;o;<7-c_>l]%:O@&2ei68IoJO0+h#Sh"'0C)^1=-qb>C)SQm?)ac!<MIS$K[R*=D&XI6BSA=U@&%Vn*4p`Md0OV`c\ Lf%qmJ#$I?5gs` ((o"]c6J,i:^!gAb+Q4rjk9;[SHo^"&d$@=<^N%e)!AZM\$n=V`_gg:.;k5R8*aOU$&&p/-Y-IPf:j,XtJ1:(HmD"_PfOU'Ao@g+M!s(G[f!<K!rfA\R20YtA!&B8d_ PqD8@I>5DHA\c4sNW@KQO]c_FBO^B>5B('FV0`?C36-&h=ap6 ;KHkY'28PtoM00:m_!:h5AK8<^)O@&27VPRr>s5L6CFB9ZssE(ZfTdeGPI$T;hX#ksB(D8OY[:7_8oD;` ld8QA#ON4+:oi(Q75g]Uh#'YfDJSR "nVWiP$q'>(R[-=Z8T#WI0rWo&k;0<$\9F]B8O5!baW)45APX0PTd4ST^J[F5moRCC0InB)/t7Qcq'tWL%5tX!]Q)E`fN38\8$hGDg5AA:)e9cU;qGf2AG'2Wfqk!!j.SV2EYn6a'_Ors;=[F^6D5B+M&9Oa3J>E-DAMA#[q4::0jp[l)h,:3Y*IVcb/"pqV(EjehdV:&\X&]'f@ffj4P;)'W Cf;_2-C0Ps_tJ$@*ZeV6)LfY[a2U.m6'VL YFAG-)?-D<`8!bYab.GE&AiTj?*V(hAsHaqNHUN&3_M%(Z3.@NB;%gfi0.aH,XVl8UTlG6gAlcZsgYM\7ZoEb+</?@ekq<l4'CTEAqKW`rIU1iJ]_hhm.8Rh$ah0@HqnkAG*R8Rod6s/Ve#ht!ak4RMo`k`8N*3:LnM/5lQs*/^aR"`fKSZsCYd7?#X"p*A?491oA#Ke6id0*NV`c_3lZ.21]AQqH;c+BcX!]XXfc^.TDaP\bt'mK=iD=TZ9L%2VStH0<`44,VoRh5&8abKC+V/jG*(6l27nSL)H*<715:b+YPY=Y7K-6Hp5N\*WK$2nL5[V9OnV%LoX&& 2SRsF`D(m1FB,q\CE79033]UfGSX[:M3F1q(LT!hjNATto:QQPe7Bm.6A0tBfSo^-@l27HS3n;":<K%d6i(5CDMihB`nr7,0DZo5t@?1>FW(OB+m&g8AR1<!tHRelLAP"?FRcatTtlCCTkWM6V3V:HK"l#ofVd]9F!:ga-R5#a]q 1(Ao$.i[9*X1M7_MM_gML^Y2ebP*9kt`<8TqqN@0VeW*8c60)(dJ=Zq#0J_^&4c,;NTBOb- .=D3BW3frn3i!-h&r=EA8*ts>BB`NdPmTd8FD?!9*NHZFQ(*Hq5kc,/oJ efAmpWGYtP+QHa#LqN ;bGd<F*nq\Co"7k!Fn?7'BG"MQQ11%T^ID'J20_0)@lH#bhK\#^df9*=9tWE+oeR$o&AqWe!ADKV%kn7RHUNS;sn:]J"K#]Bl[pmh@eT.1=k*pd2pRs*L5IKqbi9t+hA#DK96Q'fg1'fC.3*h_(j $7Q<`.<`'>UOep`3&Q*:NafN6@+-q)%l=Bh(AjZjaIsF!32;'aP31I';WtBo"_DEk<#?$54O4mOH6YhRTp\oUZ=JTEfDo9*H@I+/A`/H$)PL+EVM 3R4nR1^jOc!_^?`>8KBMT*]QFP4_r9a&M-A/MM%9&Vqm58C;IJPMR&!nXR,\6'D'mFfh(TN+.q#$=k><h8cRE@NgXi.L"X`OrKc4ApGa+ .1o$)nkM3qJN^ FHr\P=f5&kdd`Gg$i3GS@b/(2Jg7#5>T?5t9H?$nYX:@=DEFLVkgA:'j<go`s].(N0lDA-f0Q.^:oE6"^!H2()\A"<9*0W$*7o+U44n,X[Z g2\E,e[d6DV/;`@D`FT&&,":snlJ,Q+3siD&Yp>M,?dGG!AIKHp"$0!KA%2%!d;(#\TG>ULXZ]'24H?Kq-hK%Ee]18#S$nTE*Q$m;[-:@7GI]r3$#bNg26YaDRCdb1H&G[]@f@&!#%]7o&J:RpN"J:Pt5M:2;Af00/b"F.7!?_r6gHYI-&&l*42`PqXHAO&cK1S q-A.dej%g2r_N6UPcZAj'/Q)iMYQoWA!63at](rR8BrAmc@5 g>XK5U;H8nY)jn;jRV$p.%cAZoJdZb0.U:dba+h,[E\Hhc6PF(</$Di?7!U<6-@#i@4h"%0$RL9H-9 t3KqOC$lhECjtH?#CF.Ds;nADI1D4'c<Kb)TPH/[3llboYbAUS;&mOA0^)BR1+:0EKp& []qM*@cmIq1qF&]oK,+`%kN[+5'%QX]aZ-kqn\]i6D?WP2K^_eI/cj%/pA$OI'7RW;:T.Gle#akm0_);11H/o01^BBKkh3daC]5nc/.S6P0DA6]r13E(41ZKh.cOJ(>h]l*!O-%"kg9[A3pWJT(CXae412[=6,Ahng7YjQ<>VoYsY>;?.56aQBtL,B+c(9:4]43_H(T--b#jp38=3k]5PJZc>mN81oF\,V))#F!FO8pMD:$BI,H2C\n1(U[r.G,2."jbEj4"h*G'5CQg"*o-_,o9Yq1"=MFqm;enNo)2me[s@t.b1,006:h*-7kAL!,dmGB%p3.[dh=meVN/,;r/n^Are4-1`MV4rN$"q,n-M0s[K#J=@/X9JFr0/(gle^TC=,-22CM71id:$F"'M4hWk9mU<\GM13iO&/+F'>'p;UlE'M$X)i2^')8V']\)W8i1h'=]!;D4sMj$7fO0=[r/O;G&@%:E]DJaKDVX0b;LB>1H7\r0+C':R5aq1k_kUe<Sf^G&FYW\ n*O5$F?B^ink#a8/QOhAlkDiQZ<H4#J8!YL-PtV\#\M6im4W'^m`a(4G(Z0`$dYfrTiJ4:a3L0"9mR]<,;rr,PJD=lKb07ZoQ7<@tigP!c2UMGq6.6k"18P"%/c8);Y-)?4n`pXkMiDD.AdCEi](X!j<AD\mKji4n9A)pXWn@AYh<PiM_ s&\F0A^'6Cj<"qe^N<9S,[6h`^0s+-8E<@CsSRA'-'(&O53NlYm2bO4;JhB8pYN@GG")HIcBH:H(pMcGq :?F[04Gkp6$A0AN(!a-1CpnN6U[\[#3%[,FB*e80gs&BX$2pM^C6nk(m/$BQY*OGtU%5(W_A0CAm1 bt&4]UX\t)QHE?0Rr<eHQO;7@o8A57QLJ=5?s+4N@AfN%n:>f.BhFW40Y1^AN!bM][3j6#88q33ddAoQ5NEQ]ZZ<5A=(/cN(5@UZ&7aZos:0 pdrGQKe+o!!c !I8N0Tq7N*p/S;Hpcp6*<9ZEG+V%;SWHk%eQ7hU908p$nboO:5E'(Gn'BG4)&E/6C?OMF?ZW`(lq7QCfPF89#`\SE-q2]N2nstM`&iN_ '`f6Mq6&8p+*TI/I.!kM2c)Ibp+iC6Ll\!iB+2gP/7b)?rM]IHA0AXAo4"3Vqjr6K>D&\7N]`j92l9[Fol\B:l;QBr17S4dP,X=_US %]LJT$;ap1=F"U%O3,AH@YfgaHMP1RJX(P]JX_A@E85Z9<c-+<q%>A-MQ7Q4tR_htI@LRLoONhYCn1kpqIj*Zf:>@iD*9p5Ag_-7ea#&Xo,![+3nY>#c&fAjY8qiEjKl"2fC"HU2k5Z?(VE]lc2o&$N].k9o?*/;TZao'g+`[E/gpCbgp+2[B8nDGdtiqU1t)HBNMn4Q'j;b<4k,.V?XIQbon()B8)jnL$)s.JGUo><)]=+#Ha=+dLlZQ[<$Hg/@PD7fAi).d5*Z_F^jk\K`7&9#>W3V'1lE;N!`N-<0-H+R50#A_GJVdB3>@g^XX`4iI3 KU\6*/:BNo^U-YAlY0L`(BS;EY/rHeA^m[]t7^[dMT!-70VfUgS5`W$mH"OL'h5pO2640 nVA[6'rDE6sDJ5;U?[52?Y03-h$jT#6K23$;7pDLR\8g?SNojB!VLtchs`MR-75n.`SZKf? ?+4lTFJ;jE6*$mG4'$K>BSZf/=5c/IK&&Y`MARfqg/E ?[3n+fd&NKKe-HkFVch+[3ojgg?4H [5<=>]Pl 4?Q9Y\4gsUq.AGsHP3G(#^]6nILm<Ic,Sqp0[latj.Cb1$_<'&M;A33B=!?E GtR8J`:*m5AabW1TAR3tA-,&$UO5*-.H8"\IWSJ3A98-RC:'JBkfU8$Je)M0*Z2(/Egs>;9dR)I\sH2dM3UVKE7l2aTN)7:iKG!$PB>`Er)j7kP:HW[0=Ad@p_(52`>AXOcgkr0aM=UR7!KFs8Q@06JF(.0sSM-*#Q-&+Qp$q=JX3X?O`EC4eAtJ7fP^DFRR>4MT/jnZLqnWafK\VL\!Fcl&j,?;aO@WCJ49e>mJ=]d]hD]qml#mDsM4t'Kj9j@@jWp:kmmo<RdjA67"C2OZXP`<GFLql<Cn].q:kD4qk#@AEhl(%f)5JX.JUo;8ENC9L.C*=k7D&#Xitehq^?AX8#W1V_IkZNllg!C%\4iPh>SU=7Vm"A74oA+SAe^JX,<BmeQ'$+h=c6ao'Y]]T]6CgM3dtR%=)F9Y )&*k#PL;s+'H-FD%-70!r;6g-\g!tCPFK'X\#qB"&:@Ge9((AWB,Z,04$^f4_QWY4Ao7C1F.HAg'Vg. $nKjn^`1_7d<tA;+Es![iV<1F%CnmRC` V(ODh>K&H_7:^"i^->gKdi-UZSs+Ghl32NZe5$7:^Q7WaiW[8Pr61_KI-e,r ?%4n iag8!+,Jt.A<aEV$7Z0]#$?#./o^L?$W\ 9`,EHa*+f"N^:H5)UXIq"Xj't<X6n2b EQ+$+H9bE?[*n*:1dtp<P,!^=Yk$mWnArW-UoC$D9N6eie2lR5cX_rV9%VQR52sc#!:dH<<;nWji^Dj aQ+,k:2_[0#o6KMKL,Sg?0l-4Ps0P,Vh'S=5l2@hRi* E"iSB$U:1>*:COLpr_HK$;_ga[H3E+('^")O6n]N@#:;dl?]09dbH4g^pS60c^9!>RF$PioDhJJb14(oF\AbC&2$JlC(;9g>DniH(`tN'>5aqA#3[mT\9(F&!J5L3?F.RU6M9;'=q eV&>Y1%d]5e9?ZE&7D;>B*-QJSr"O*WF\S=c(qe8#N4FJ!7lCIpn69-<SeqIt(UoN',d0Q:T2o;>3B;W^+6l4&K>;^U-R\@b13VigD%Y.a/c<Nhp8[*1 $JgFIb$*V487n$7/1&/.TKP;Mgh!hW))%k*T$#L-ar2':,!Agb'*#'gQ`_E_,b@Mig8+9?fN)lBNUV=2KRA*4fTdl/A[o=b+0(c$Ck=r>[N?d+4-TRjI,k`m.LfE##>#lt27lgCeL_>(Z\W]$a0Oj-f+t5/rnJc+dj@d4d!H(a3DK9lq7 .mUI$^/HTDL[GncYFbZ& R60(<C7NZV@sA$5>hmHPd5FT5$[BA9A"!n[;#) (n3#5oC#q%f+)65O =tR3\(*dIjm5\)WO)Qn+6,D<iLnD.[VmmcH(KXASP?dr^ToW7;f7^hTO."4]P>9<WU2b.bj$&_K5R)CV"&7ZYTa5% f.^TFUrF]P:@C#fbBbP`1J`2a$Xk(/Aq(/]&C1.3bSV%@JoabA\R_kSQq+hH@MW*l1cPljPQ0Ir3+*ZTXD8eP.--*q@m]q?hh>'P]A9OO-V^f7Sm:__ $=L7SgZ ./&`hE )#T,R$mE"Io"_VLU4`qjO)fQK=2fS,2!MMY?9]=;1Osa^T rQ.OA]NZ/<@MWrQ4)".Z- o1,XjZK\3EB75DCpL^pl8aiUeI9p1EcH16ZQ(^V>NiA</,$R\&J9m 8I'qh4l>OBKadMKOl*#9nhBa`?_:+I]1@ssK`%AH&JhK>(L03mPfr# J534:BkK8 ^QD"=&),c0%-^WY1ZmWg8Fn422;M+I0UZEA<@-U'&A/`2D=Ni88)t\+F+`l569P/Z`7R.k=ei2;CLTo:'jGb;"<m3JcL2@NXo/TELWo4K!)*)8i3rAB4BNkbXSVOA\X"R/o!a-D>SaLdBqBHm=d;O!5Aj MCsU(AKW7US]9e"_9bg,s:??4VZ1-6HirJD"67_)%Fh7MAN\S\BDSbY3rmWT3k39I0329e<2o;0`:W:4RMdp;mN)AC+>@=chL?8+XU6t3`iI<O'jjBo:,RC5pMQOFpY)9c06hS%@<"`N_`>e2hL:Y9)!NU)97V@U(tRck@5i+L,r+iA`9@A=MF%1crm%2(YLX&.ZR6IIFZ$tjZlZm3l&1/[.B6Yl8Ug7V5m$;/ >EB4\>MOL<0%&@d21bOK@_XNFh;H[J^hQN[?9b8(QG7AeG0NmSAE"LC>?P!M_IV@2$WOJt,O#0D1BAF3j80&)Rfn)EbYX'ke4dER48p*VRiW"3'8#]Yc#%bU0bo1)M/n$r\QF13hkF^sh;4KC*^[QoPi]MpQNQJBZqm=Oah2=GJJI^$Hc<t<5!3r1E!-!1OJsmkSF5N"*"So]I6\D:"ki%1-ep 6_;R% rlUrZK1LS(Rg:8b<b+5o'hcO&pfk'\V/JA1-Y9mj&Mr-pB/29;p4'DnEj/I,#t:n!;94qE!2eaa8t`l[-&PdfB?BGSSnti/lgIq#<?KpF,N@gn/pJ0#%(GWoJq-!H#gXRmnU/n`,Rl?'9]m<ac@?VqH:453Hg@8Rr*^':?"<m,_3\D/GbMTa^D6A^r&%7i!4Kj2_m?F'PTSTXBmd'mc,:"GfAph/Oi!D[",k*'?_o)_0nb6MI*;]66oQ?[UDag\01 np6W)-Y/2AVn/=aq@_V@8HVe>K\d%_e7f$6=mP\;_QtEX/_J-+F'^%4Y%:n06T]R]^Ch<t,Ab.::*leb06B=aUaWsfoNO,7fVk/H*=-lta/tQB*VUWl6mcH2k70T9kK$;f.Za<<K`iQ[`ND$'OU5&'Z9mf5DA+5UcC[P\-B!h8:=&4-d'^s3k1#t ^"dfn;p;nbf>sh)Y'i_mBZ^ib6^A%aP\sFa[MNb@GCXC/S]<'jB"jG/)^&@@_ADT^bht;?=t":ZOi9b1lJQ':NR@gU%VA0ROb^[Z5 #Qk5%cldRbrb6$j$C7.r8p<Na0r)^4pWN09k)jZ79g*:W"R[\8PGqd2;e]t5M8=)46^I).[CQtVofl@>?.q"pm=Xc" YLPr[:]nh TK-qka^LA5Q=%ktd?W/cK!old>\C1bUIL3LeNoFO7.j+*Al<LTRbLFoqS`QZp`5N\[r0`f=*k?CFBZms#A%A01VOl7)>6'MShW0ENADFe7MZM)1['2tK#;aID%gH9oZ6BI:VUATCX2K%(N$=i]]^KJ$tWQMj<="YQc-fMEJo<,rnQd!0LO;C<Yn(Zk<^)TTF3-$HaD15>dnqdL1Wc] .n@Ni2psT5BK38n@h'%PW,XRq^gH#A=k7t;4Op\]S,e1+mNgj(:9 IEO0$T&X1G^-CU/RoW_O,F(6rN<6J?SB#GY%;c=B;Glb>mm*&XI@!(]!7>sT7&m_iqo/#QNDkj\p8VTmK@$H;(9CWojQ9@ejK;`nfgOoYbH>E'MQ7MT$;nG7Z'9)^WflKHU@:Y4O;5I\FLUb5t7e:gkN"q(EOdOrehq&r!ROY3j>U;iTK,p1sJ7s1?4jN2-dnArgtpW0D+eC<>efRa_Kh?:aZ8$K1@ABgL_n,kgQ:\n*%tW;#CZ1'c)Bks@W;'5P:hg,iJSFcD$P);k=6mh#A:c/DSOpG9./#iTg57o7rU]Nt,2KN4rW/'!gVA"KgN8U]_irJQUP)7`oU9_NqSfZ2`dhX,ctR6T,gS,S^78>W6hiGW%!rJEdqX)#jsk)6(^M#cAp%@d%o]4dgqLK]5d@jg&pt.dr)`$#$WECm[Pp 4Q #0f]At_hMl('aJCsA2S/M3jiG.a1d@c22R-W<q16KsS@NRK%8A$<b*J4S\Ge$k7S<b`Wqb-lDo;ZURg.?7johY_n`@O.gA.j"D<EDl)KaAe%ce^h%jrPe5=[6sJ5(W,&#A"jr4t,mT]k5fOSl0X/Ts-X&\\_KRGm5]U:HBUX4pm29]b!&Bh*IoWaMcA-q,"Acp:6QQ]B!ntcGY<o]iXK()20/,=>Ib3DX&S^pK*qs-(.TbG^_/E/F'_=p;U\Ji-hkMS0:O4.&i'a+9MObIlfMF?\Qd=#A$pq;N+bh6j>5;Qh>$5 N!dT&XSAbADW4T)`/;j,t%IK=GA\SP??R/f9!'E%$7mK\tcioalVe2g_FeSCE)qLAstRl;mOLhksfHc>@d&\h&FsjdS/n\d@aDA_PdU-_%fV>3++RG=qc>T:(0&_G+9U;MXYUK\AO?H+s3D!R$OV]mYT#dE#g_RWkM"q(I\AB81n7S%M!VB,O\6)l9[Cl$ F["h6ARRBHh/At4ah]s<"b?4;fL[9GKmc75:A2r\0'CSjY\ ?f@o]pWN)Lo::Y,-#+jtJ`NA7`[8Mkt5T5hqeAf:tkTP[K_,GE%5A'jM>h3J@h%WG5oVsbDHOr5V9V+Kq?iY7-:EQ)8fAS<\s3WlBPJO7O]$o@#L@.bC&hDoW<#!.8j.<deSSBIlfMlFMSV$)=XP]6_r([V2O\ddm C27IL+'0ifqoH"?/,Ji$R`$!_tN4=Z\^BU&!(PKnsrC8W$*hPSh!JZ?:j5e%A<c"[4f=Nao3gOD:VjotqmB%&gJS,+#-\^8Tp!CWGBdAAD2!,%:H=@[`S@R*WNnRU?T:Oh"Z%) frXRaX=1(2!"r$/b8E!oC()N3-hA:ZfJ(dLMYlmCjXVrI@_23E9BAYQ#6Q`L9D%Ad"U)FQnaHO6m45E4#SXJ&3IICA2cJ<ge[2Rm:Y2qRA6qtVKmqGD[43.!'!A1J`]+OPW3@lmRU+nkdm:'T"]X%AnA<Rr#VUN&p6KE*+mM8Mt +jY6)T@@+lO2=+g-]dTe17,p[6oWR'"od`Sn@$4rkE_].h2mZOqp@rQ*V>/YVOL?[po`CD(-at 4c#FcK-NZ'E.V7+pq,(3OrT$8%E>e37o57[BeTJDYASSD!^;%ob5K)46%67J"l.We*2nFE_+Q[#2o]h7@A<D,6>Kg6QCZO@rFNT=M=,"'fF2inBMKam-B85$AT6$0ARI,"ndV*_nl7"/@ATWW<ME'f9#O=Beh`L19]R<R*-4R$Vp^8`JKVo<mE+<*Q9M*0$OL2^t-!lnW]fOoSca(L/ENf]M_6_<.\3/"Fldg'WiL:?*re8S-Af"tl@:Fr[8DnZ-/U2!1LUB77,j2?9\K!HN7GAGk9C#At_7\mIHZN`enlks.BT]m3?[SQKS_dd53bMc`7f/Y@Jgt43P"PltP7MOD_+h /:ibi:^[i,NV0A@6UI&?iC@hU0iOM8OG(PaF)]Qbm,l@82)4hd2;nqsj@&6sdP]K8_dH?MCL@kP XP_AA37%*a?U9sh*Q7JCo;fi!OW"Z>Gg:k39m(>t.AWg&?f"3>/Rp/ahL3dtB `2/$5?1bYrhmJLfcMKte`@/n ;s\PnT/el`laD&EK"5+(3,l*jjPWJe(E7Ikt9cJ0%Fc@mm4c3s^AaaV6B,<-O/m`>G+(.&:#aZ#9-4LM," NefR'XeH@nc1AJ?![jD]Ct+iFl[%%TUY_'I:%<*,/&hC@cWUg-2(9>91LXW^WRb6Z1Mpp$-:l[ DQi0AoqIoO`]b[G"Vn:+jA;%kO0-<5Bag=g_$P\tZ\Ufl!4Cii ;QkA\1%*dY(s(sSHDMq=oX*gK?G>A!kST(H.)`!NNb&A>'kY/-)&n'UKd',g+4$qNIQOCHPYBJ7!80Lrt;"M=>5X5G$;DHMNYQrdj!jJjQt1Y!DI?Bq)ZRZH>nCk\c44PAC4^5PLIc\g.285(6$?(c/!0j8:NCC0RiF*k?AT^qQatHh0"d(C1H4W8P>>B:\"^Ui?A\d(YB mOnh*JlA 'VqmWe\0q4-=QqaMbKSI45>A,Z>_#qfRJ#[:c^r\S2+6le^O/TCPFI>HZ8=/G-548sSdom(J?C3[$25 @:Oh<;JJA6)#$H'B+`06\Pr)o%;\`#+FA@:D7CMl8."5'AU5Y0UCNL](BA2b`2 $pHjf\&jS4<0!`nLbYrA eMZnU`,o#Q.[: )3-IZ>^(MUp29?DC.a!)r7#h^d,;D1-coAB:U;=))#Ng!GP/>"]q>9M(1`FW0a#Wr$7"cB$>#E  'eDCTt]3.FS0roi2q]J'B(JtbZp-es2]((SleEpVd4,B@X`=n,LT_b+/I;b?K )<6CS7;lA/*qA"_;J:1O=mrAgeP&JekLD(Z$ffEi5O(E79KWOfd]SG@7@\\NM$^nV_B/US&U7s"kM%G'"K!&?gb:%Kb82?&'"*Dt^bXt>k9E'h,Bl94+.Ns=el@F/FC\1-sA37Aa&<4p,BO5>LLD/c2N@01M\pDte )*nCBEAN]bo):3V r8BdgCl Jq6TUiF[>CJND$=UnJftI5^ApC))lfM#&RX*lFnJ'h5c@/WQ14=GCl'6o=;No2"C"JI/TgW7SViQ/(cjX>M[@.K8?RN([-2HrgS4B.@A^?AP2??N`")AN+U<@;BRAOX5=9<)\F/B!sid \]R4qV(INR$/o\<Pk&-gc?iO,5B7njk_6]3dW?1XXpe#RANAh@2KF'\:N*P\b@?SjE.R@::J-L:8[V`gH?3Wmsjm!_Z'K.H:mpQQ?UNbDjf6*$;S#6+C2eItQ.:Iqr2% CQ`VJ7t(&Z'[ZWcEZ9YB[HeD=tFDYl^a2+=Sh!47W5YsN\Y:cXME$Mq_4SE:Yj3_ T*'/>*\m<g[me*gbD VfKt)=NW;/-_4*S*J;Q_(j5]i$Z">(_8eC3ki.QkkFlPkVSK2?HWAXqMY5*L<Q+V:HU=/[P#l*TEt!fUf5..0q/;ANor()L]\1ZR9YZ!^qaJt4dWt$AoGk?B/@jn?;1LDiLXq:qX8Ip`ciQ>87TOE`ko<3Dr-QBPV >cE<1T([B4^_CgZ,4LZf!bt)t9iVR(1kWXpj3-rrq(aG_SZM&O=-2QU37V@gQn@Sn,/!HqiO-gccspXsa1$%e, ?Vf'5=@/e_,It<FTB-]AtMt$Xq0jHV.>O*U2`3mYcqB^eZ+#Adk'>A;.&2osb[=ZEO@^U#:ifJ<;GgZB^o!>D5Gc^/Hq9XH$KVb=A?c%<Oj4ai"%dcm*%<RRQKfJdi#<hb!TsQ$9`kBADMEk^oYa;l5&4cFA<%+]A%<Ih>DI294lh+]p[^cDj?&J/CH>p>,l/_1E#i?-YZ-)._(QrZnSc5?KekMbBPs;]SmRbJ=(P-?I!AedL*C@,$dqDm%P&*/*( g*qmb%q!nn8.hs\;nt!UUlXRVsAQAE*#qaO#Y%E)r"LKQNJ@dW"EfX)+\Xf=5.TH3/>dJ?9W tU9s#&CHsFT =c`3DHLNJLkA1cJ"D>aQJh%<X8.h"X.`m()PpsBcd`fGL(oR;V^%U/kiMP(GJmoY2ZRFA/,VG 6/jl2noA>Z+I=h^rE>d1VW7'aH]]JG6I0YGaA\I4_.$q\b$R:pKB;n)m>%K/0l9LG^(bW1$qiQ\NbYONAA%c. ;:PFQ++0-E5P^s=7^MP8$)rr47`":&$='>ihiFb/>A^7^3UO39<>#]l6N[%B8M$t2jP@%RBeVOYO0l]pOnrFAN&oO:7o Ts,gtoYh7:\1!Bh9)!XOeCHYE%9C8pB10HZh'L-a0$c3AS=r^a67gCNkVht<`c_]f>R4ZAitLW!L;og%CIJ*^T9RsA,q1:c#X`UI`K>kJdN]*A"qD#1.Ua/!FE7e?JEj EGALbU2cdRpPf&=$do/?2),R]p 2D(HtnNsNp-J+k0V;gb6l<gfhoN:'4`=_XeXR ET>2;k$e5o:JBCXFf.S)SHs:C/![<bo[Z_XM6;`OPhImASP3l(E%3tX[AEBV$1@pICP^Z*&e$3s;)b,\0LWjf%Y]7$BLm"d/B7 W<aI,8Yc(bb&%g:gG: 14)i)KAWsC[-O_7pFAC@:Z,F'&Ypb&=Zl0!Q!JOG&_S#&[@+1a@!<\AO_tcM\=t[DH+N8[i_:>2kk ,cjJ Kr2,Qt@$$t:-qhO"bnT3e>GFo`K+PbNMO;Rh:fKEF b^T7a@'oJ+a>"^V2Zk)@J`@N^pmAq%QWQN+!+M+bt90mtZE0 `g%qYf,qqqpKg+tr6`aA;Of*\RbV#Frr=&+-pqWsEFAZ/&ToT/sW&kO_7Lt4FL-UA:phLq#DbcirKJ;:J!iUhKdJk`Iq?!8S=dGd(kA8d;klrp4J+:88cXMP*\1)m=,E9k=hd6*I*90X90`?JA1dXAYfX!D16fdaBiI2gA'(;n"cBp4P\XCih-r#GAN3R<%V0<q2I2WtQn8%:*V2D!F@KPQf[A1`^V*qr7U(D%1C0t hd!_.2J4'jr-]MrGV+bo'"EoM:^a3rR^#fm*eQ'T$gA/d'Jp>5c)Ad)p-E(Kqk78CE#O'\:KZ.$GT^d*>)K3MQq&G=R]"2OGEqP%;BH#9<f.r!D^/1tj[ik8tIpRlXq@#7H8R3rJB;AKNR;68#k&"1O)^$.PB0(p]pN$R2i1>-%+i4*lhab2R3M5=b(`WeqJPG@;KkT,dQe)M*WF>&D_N*ib@0E#,[WS(Ne3YPtT -;'m-BQ,jbp'eo[pBjAF>f#h2b+qRd>%^++bN`P]?CNq2Ks$^/XnGO3@G&rEp\_&AX7XH,7!gr@**7'BiS)pERcqFmntb5'[=Z"c/#p:(E@_eZC:p?kPH=o:1p@3<DV&e"32@[_UeiHmJ0!:O(&qs IY$4-QQAOdd3E[`ZYmEClsS?`EMMri+/A5,= $A=tYa#SY,_5l?`F#.9"m0:5^:WAV q_6PX`d8'eSS >)J$\A]q'*C]G*9fa`jeSZgj2laCfVS/+Rgf9=%S_KB[8,l[@`lR"B[o4mBA-dY!UM%Q2c=13AZZ[6fc1["[9g\"=Uq5Dl@d4n^K:'982?V909L0= Y\5AlX1V6$1m'%]"ERYJPnT)Gl#/Fc<]k`/U.[4;cR[b)j#q4q0Qpc=c$eAr-5V+n8(\DNtiJhPis3:@<.F:[`KrKL8W\i,[1].b((pCjbj%LDh0?H$2Z*)J+*Lc`jQZI`Na.k>`PhQHNn2A=OJ@cppcMK00LPg"L@-WWZ5K<BSbLspU\@C<WdG(L.0srsX8XdM['n=_"PZ^3;e\qYL6fAC&_ nB8q!!BC8%OOH<AI)LmB*?$M%l),>E#s_ldV&Mtf)3DBA%!#?1I@"`-^E^=!X]4AVDEQT#%;70kd_4V"dKX!j^/UfH'O@[*IHC(b]AZ$ZhLM/X!0/Q]Hj*V%k0mI(Y8$XOn\.qIn5/e)B"I]#/Da6V\'O]QkN_G)[I=8'Y(Z_.RqXB/)[MIAq#n& +nm qtG6g<`OU\iKY/dQE6D5kNJV[rJ=8[(S8T$Ig4eIP_Ff),<Y-Lg6  ?7kM]6f@qqRBc#'l&c5+(&:EVl3b&X@.cN75BSO1$;i\+E\*3"9S2"%6p3Nm2h_RA:cej+ESdU8)";5DlLlMcKOnT3s,\-,WoA:6P;"k%&Yq:ENNZUHH@`?1JHR(2d `$:U,WQK.$OS'KQn*;:-2Z^,=[ml^t8N=%6R]Meg+b'GoQ5DWU<q#g([:WBVRD<Sa#N$;T+)bC+gm]pm7]na0UeM'Xg!KICC>`&Lp!cC phI)oG57]I6<N\U0>PZ7ciGAcfh87BP]!`AMF;<5TcIYXOemL8En[ag"!hb]T(1\M&7[4C]n<>X,.(bE"Z=([5+>& rentPm#3'4/>U[ mc^#Z6rV*\t$LgGp3$:*IG-1.25FGebgA4U&coE".Ab+j-&ZR+E*e!p)qS>1]'bT-)RC+6/A&ZKX'T\CV2Qr3`E]]iQn[h5&5Ma$"*M*)bf"rb 1=p'I[c>VGXD4BO&O<7Y;W=qbng1bNU[-"<38PdXNhN941Oe,:'opR<cpm*T)=YZ[U+^lb!4+T:-_3)P(\78hlkojE!!m%qq5ZX'GMA.Aa_GfLITm/*r&Un0b88@Ko[;dY+]\Kd9AsWk'(]r]8A]Gb&^:W;Sj)!a#<UFgJjdBtmChsl&Z.llni*'T-"_Mf#%g_Al8;b5j'rj@S=.mIZ7ojf75;'3D/$*P>3b^,0YF\\+f07p3"0lXp,tKtrIL.0e^*.pf'00aE$R#8W]O?4=0QB3LUr?mkX7B(m;)co6E'"<1lQtfQ@5mR0YR*`FFYID+'S0K,Z(nal4ssG[7IS%s^48pi2B,8 (A)KiNFLc6m=&O)5j2 ld*[8=I!/f h4\G#i>h?@8P#VEE76!^E)V!l$DeRMMriK1&8NgVG;f,X^bfZ8;N4$nqP]C^A\%?AmO '$aWQLR^Va,+Zq/p@aiWi?>N[Z"2S+^e]cMRH;7DWNFR1OOaj4sQ^l*]XC`tZV8T>FWeS8N`'`ZmSGbb2eSFN!\>bDh=Mg:S!ks4EOLh&T0[*TN_`kpiT1=?:k_k;Q0I]3Nl])gbh8Q<Mb\fM!,kf^g0SiACn3fet?)1G!0*8a%iPBKq\[R,k:#2^C8>e[+!k4U1g]>XHKo9tgI1bb V:/`F<Ta-5AmhPmDG^RO5!Qa),VN(QQ&B:l!J%5t/$goAC]T P24"<X7?dlf,@T34ZV IWKU8&4 nOeO:@3TsdT&QDt)-fAeoar"O"t$9i:jHkR.]l1b!B?<60LU1qa*G4(#EbT&g,JK;Mt&l6SE'<*BTRst8=MXMik.YP=&VA jG'?3pGS1JD'm4XXUPXg@KJiN.5r&9_0H,4ed\JW5RIJ^#gOR2_Gf4J!W6C7MX`cOt8)V"8]?a*8#baQ9^,tDU#(%QLq,OPQ(kPA]^`sa3$@NW@5@2C!,V">Vt5e&D/pg:(d.@+Ti`LPWE+W&/"YVOO`C4kk nOkoUl jY0"< %J9d,%lsY,a]+`A!Qd$WR\n:0DE(<M`Fegm=apA<i(A<\scW*^:1j@dAQ-5g$ommh:m*M0tE97_NDO!*HDCN!c"8ZC?_0QdHdR0hP_s\0RX7,JjM+k\>XF nG9G?GMXFO9&eBQcA$Ma3]LQ5RBX""7_De@DAoZQNAZJegBWjA36hDcEt.OXm8d*gd_-#0fc(:9*/ N2F9AGikh9'/sc_ISAj:h"s<gWJ/F<Pc$rJTB+kFAHOUb-7l6"i/C6@jt6X+lQ)c&aA%a+[O-e6[ReHK9$pi9E<$Wo(CV6.*7M7,m8[^7p5A#AIIcVqGHt AJ!PFdJc!#ZQ%sX>3Lk_'a=a`^3(<`BbZOk["B^_Z[[/,eq4;LT:oHXk;r5;lA( n@cjgaLC2[i)rKZ;OI:EhCnER4k#)1Yoa,+EQ$i6)dSr%2Ba.i3: Z6SA($a!gl$/nC6>X0EE_a72CE`nHL"`ZGU_5SWAA?W! (WXtM9Wj$I8P'8dij.S0aU*$(MBK HLH6'U[tq#JP7->J=na1WgXIWFkjdW;1Y/sUn#bTMqen^`7bA>(^c[!Kn[f7p8AYb(N2%5\FG-L0^5"qMVFfaV;sBVm9oiEHgj8H#OYoUjZMNTL]MqdZ!s]cpa;;lN)0USZ0k+_G!MnioBE=e0hs3r-CTIilr>3q]9?JfI)sNDPA#dp;\3rFdLnA@Vlgp74%r7>Cgf\N4eLYHU?3*\67rK]pP cW23D84fAQO=2,.p#g4RL\<&QdV ^;qPsYans`GF=XZhl-GE%EW5^<fLR8Mc7rU-$*iEL2T/ZkjAp&o.scbL;@g\c2`Ut7*/r:\Keo]K_bGOH2)[EF])dnR&TAp^JaLIgA!E^q\*L0aAH;o!`+A6'OE63l^,%c`P_X3/0 -1b3X516_L/Dmt`5 B\A;NM$kJI3g-**5J69q4m:,4kr]0<L1`rC%bH@DlS,]m4^6XAY,A>K=(+(V=OtTqc&:bh48P[RUX/.YKGC]^DA<><6b=Gh2Dq04>^*V370c+O5F&r,CEhV5fK)nMfG)Sr8`i/9K-7fO=b@T+\J+7EJ@6klM`Q4^Yf+e^kXIrNXAGn;/:SJYhcqAr=0shWAs',%1sM.3OZQcJeJI`fO4RV]9g$#h">h=C.AR^)4e&Q&K5,iZ-B(t$:NFV#FF8tY^GHO5n1q#PIMZ_0JrgF[%\I7R\CK5A:-rc-P6fFm:TGqbU_rjs$q+O(I4So>0[ApW!qQ5IQnZ5GHgr=EL-H20@6Bk(AV$0UUF_#f9(6#g":j!<iI!+3'S0AK@d#1A,FO! ;MDIY!d=Xf#.(EVm;^>Vsn&pX)b477Sif2mg^V1$*D#_.DY@_CmmU-8`$i1,h6^8U.(EtH9<m]5og)eJ!bbP[b!QGEpJkP@:bmPkCONM-(-`U]cXU]gC"%Mj,@f%/]*q*9;UYd9!)=Ne'4Z7rtB]b9pj"dpVkMk<Ai)F'=H Bh]=D#&BS9_cTZ]-B`b`F&?;N6baVT8Fr"t/gerd??\<J6Q1bLprbQH\C?&cHaVI*<5>A4d>@k<(tQjjl"\gQa7PArYdrTe6r=Fe=T9cYL&@LU6=r5r]hD:o42!1ARde,?dMrkU;`BbNYcA"=KM)hRQ`r\hoQOAA37TNtXr^(6q9@=N9)j6I!8CJJl!pg-_M;tMdSa2sD)B&*c8t/dY0;+=;j)*-03I1n 2I7F1jpOc(ocb%%L/XUj\s$EE2<aC!=>[!<;]8k#])^N+AlXfNZ6/jO^Z2^!R,"s'd:k<[[^ig6Z6W<#(\l5m0+^GHLN:tD`4,k,D:V*HTp8)O_K7DO[>f!AM&]rN'< MOn)D"o@mK?jmgi%FltcD*0.@,-H(e6!!F<5Oa!Q)A4OHKi=2=NDBR6@jDrV&Wj.p`!VSUb0Gh8*Zjh-X[3(Gg3Nl0:'`YMLhApqnB0#aJC$$_67?8k]:lA:+pqsqs/Mm4jBpTGGsKA8RH@k$)kJI<+c^HbkSX0%Q6i%m;?7J(<X\V\G.lX)qP]=#7?7HPMQA>D&q+P0N@9)JKEX!8dCA0b"8TbCZ-4C%L?#,4$UAo`9IPt"K`Sf`b$7?,ne4fS';ok_3l4HIS+7H,JV(5[NqX4TO0KdO_&'"*ZKDtK30&f;<?lD/2D8O[cWP;=*.I.YV<lKc;^rDL)J(OgJN/e4Llt[QV;l=qRjX.7=!,$.X15V:7[?[j/:bf,_PN?[&7K9+`.ih)Ce^:oh[ArJl(9\+)pUl>;*"3p#]t1@ZYl82b^sjLL,;P)$tJC='b,pm1Cm1CoL1(]URj,HA?_J9;VST47LXYmIq.O^,!54Q4RIsp6QWdbW9CZ0g-5J;Z1i^4bRIk96r.nI.jUBUtc^I![At*:&UE(KjS(/ Jd]<V?>I,aAkEn]?QaL!&MV:b0tVF\$_(<SjK60T/r[q;Pt41mA5qRC]BRQ@pX14>fq__Uo3W'>*p+6%E,[*>T5hJR^FkJ*$#43+VhrK&&p"?K%S'r";pKQ_1qb8JL_:#Np5>I_Oh%>m3;' $k<As\P,Vt*bEObBn,kh fBU+nb_"'I0DD(6l<oTJgP'T4c*.+fp4JsAP^/!;;8Xod!mJ@s<1Mt= +pNUJJb@%VoPc.R/,MS'l?/8OG/H$1,l09FJ('-2]H,!*2d2>A]i&P3A)7WUXm*#ZnF7kU 1WcU4+/c,^ -0gAri,BK K=cYV*G9sXa#/#<iK-Y]`m` <?SYcX!]$%0N^6-<p.&AGO.s99D)Qi*aPR^QNn;XEs[#4RPj`<*i$/LAdh>^jW GtqIn+LA4/bkSW.9MZ)ZRbNBKV_LN\>$DohPie]e3?rjWX GP.8#A2O5-\7"C,KPlP5Y&U2[KlMQo25q.3EZ/#]X2UYU:gAI"E4Yd2`IY%O<$ptj+Y5]LR'G?P^<NsgI_ReKZpmA;8UocDq?Q[_Z2l6O&k3#f"AGEA(!3ZZ?-MWZ?HFP%E@kcCBcY-\T%5'#r>mRdRd'qh/>A?D<V1=tZ)4NI)B*EWZo&jmiXAmqmZpcdMPN0mA7MEEacOQF;k,<!a]92?7Q#=KY;>ch4Ys!%UG'FYh>6K5g'Wo]c.oGTbGS-?^eAW\3VOP=+T)_WecM?5/9/6e//Jf,$7((V@0/%O_k?8A&H!C(gZA$\lIS=bt.=ZY@%!*`3#1(<:>NNP_$?-H;O/FPOsqr#q?B!C3%4*:JXFlF#cLCIjr`AG:B!d'B:ai=HEr&4cICiI=dGf.F'X;M6n5/S8'LkO6,6SRf"?UQJ 8,8[=tiC(UO]J/AYl0_?+#]rgkV$$.dI 7HGbO;WJ8I^^/ZW:jj+m+ZRir%>jmWXkmbC"Z$[TT\)Y[%)L_O+>NLsS-^\Kr>eStgZ#G A:R:mQ9l024<FA'(Cl,B&kVWh\=L2ERI8@k($PEKC9gDV4&.Z#nAD@KmPcgt1Jr[\\6(orWJcH[!Z2B<ikM-PQH<$pmTY\`'3d.AT;,tq<cesEdq78?HYm6@#LLa ]FnE%MAW6'Dp`,]efmi[_-D=;-rB8'DIN4<PEcrM>Xb[V]M'lGW-%sjY%:s+b?o?Oqid<XES%Fp1)RnCg@Ab6dfeJ=tRP()n5i@VE;W;jJQaJi_rNk5gB"LVAoe%SAp1?F'I,$!Zg.TO8r&\c4Tj?V(B[N!&[p`Qe0;b;S$;]A^mMlFXhq^Ye2LOI%`SYMBdf>&TFsJ@HLOL+=1SP31P hSX@eR@61(H7f\W"`mdPf:JlLE\%sVboqP4m\Nq-1j^;jA3521f9X,Aj8 h61c=0G480E30bdNHdj&m!Dp.4OQXj#aaF!H!=VO5-2R)NsdM]o;)bs d/2NC8_'%hG"68'4CP22i5 ID*8>Kok0XF^'mPq6em/"*-0SQU`KfTbIF."oVADl9.i?JbIjp!>4;qd>\/mJ%tM9S^(IBK8CF!'a:/*2^=R&TVHG1AoIgh$;4MMC.sTZ18b@_Zo#F^a'lH%VkRFeh2WYgs>2'$]7o 4)V)"jRBN-OqbfGi5`bUbEG^cc4TB*.I,M<9sX"\hpBYZHZU&@Mp`(t:oi*W:4eUk:j=1q ,E77#5=+>#V]iiI`,A,]$+;aTN]qO^elX5gd1_cZJ&FRjfe50o5YP2'/3.:tN)GPGsWD^3FHn<Po<9t.kFBFP/9mJBM`>qf7Y)jBEs,'lX0J\@FpCNkj$?;b53k3K,1&Op =ktW98o6go'DlS/q$]6qIlD'XPAPmF+52*KkbNsoh;Et'l?WA^MS,cWZp(t5!bSfAhfY-_Q]XtfE,'-9JKs'SPbdC1h*.2MmDb#CcO5ZK4qR hc$;0*<<]G<3F)bo 'As'2@+[.Oi&<\UAp2/fMeA.>A6/$Z"R/ENAd47X+n*=b4Q+FRK00@a(!! leYn1B)b%]n7>`@,nF9q4>7"BE9fLGLt1!X3%,!\R5KBn;AUtn2@2m,"#sBAj`+n(HN2KR7c2Q/&9'N ^XS:_/A'igE2Aj<AhAZ6$Fft3'q+OB(1$aU=,m9X;.e Y'7'NM[0iCbgc&3f-IbkVUtpXrl/j3Fo)ola>G,k@@A^R,I/t:L?DO'U2Prl1NJqr_k&<lnWkGs8!hHDhcll%pi2n[h<GItgs0%5\ZL<AZVMAaF6fC'g7!rRX--,`]K^0V3-AYVLh&(K`i^C</qj6C(geKYFA@/n_<LFFh?pfPeP;eVO$,(]]K?i7Zkk]`%fF[%c7i\RUKTnKcM7]NAd^e3=bpDXtLGb`6OAQ&[<Z5HJ9F^>80fZcK>Og<s-&1HYFbg8i:+=@8TC6GL^"HdhZa@D$#-BtK;.,Vo(!keiM:(oDc,3m`!eK8`/jha2Z&Ch5ohpX1bFM8KJ(4*T_*g;DQ#N/SH*GBlsjtIsQ(*>'6c3$J];t3h6CH,g2P/MT7r?t,TKRN9\;OM3RbVC0bhSX_6F5R-M# Tg!EoD%SYW*1Qb)JLI/!MfTZ5""s:8<fd)7^`*M.ZA!F>Fmr0*Tp7P$FXqJ#%`#=_H<?MT[%;fhQrT,R.=80>i91XEeFU(m9+m2hA%ZW4E[?l`=:QW"mdF>Ps03m<9`7jB""<4<6$-`bCsKjMAMPCG2W BC?^;O17GSDg1l'"Pmojqq0\C^,I_\).2+#%I?.kI##'n*@PSh /o:lPp2Z4b7o0EQ'c7%>Xme8V0/+A[A-_n\L\l)=Lt!%c70O[C(7qZ&Xk_@jh'DphP</EV`'W[cV4KO_1+b_/GBE0&O$\aKSBddD2ne#fjf],/]]cZD!3)XUJj3g7mPPs:L#THo<Z&n4>/i7p^g2br/7boPXRH[Eo?l];bY6T&LrD@<b1'?tp2Efn$Ai>4Zb mjUf9>\b\PdtDQ :AG\H91r>R(6g6qAb$<S#hlo JI:@*8EHoEei9ARh9iB(=.NH&4D5cDr#k5jWaF>7DXRdjt&#mdFFjNoXE&]0FU;,LKf.2lK`7In."M0#RCDI4:C;p):5PNIKrL3?oqj=BUQ3;4 AVCAC&1nibS^kES7a0kLA50\3((0f?85.QdN-/k:in<)tFMAkQnN#Aid/G'-+((:Pf*)lh20R&gpeI7U\Yl2k#r3OD%VKs\#i>oggj6J8"N-QlI4:t=+raJWD%Fj [k"AM^O5frFf[K$SI?eH2b,*H<YJZnt5(@Ir6VDUKnPh:9lsHAn C4]AD&Q`"lqil1BAIW+FfiQ[K]K="X'dM&Nb)L*R!A?Yq1C'gS(Y0#U'52,4&f5$">_FN4iT_2W5`Dk;&ib\_qM+VUPX*#<Ftd(f`XXa]BO';.a61BGK(DaU7XWs^d* f)=8R\0C01IdA(>_o:LX2<lI18nD[aGi/.oBOg(s",&Y]/[.0Cm4!IPP7AN-tDC@o;5--DgBk\kF'WV,>c1!mBV<XThWa\g$m]O!+H,\9eSo%+^'A:iV+#"3f]=7d/^gA?GE6%HH@9rXC+ObJApe><4l/QA=!gg5c!dX"1f/cJ1P((2,_LkH?hi77HZ0I=A:fO?4 ;$FnW3F6sg?Oof1g'GCA$&]Y)..5U76;%d!Qn+-kp0BTl'km"!0[bL%2]?d_Br;oa(Z>qta.#5A& 7P;BhDR&rW^c(N?H$ZG&e<h g$)pfAlGAf;B)gFteIi2E:N9jGntD&QPH*InJkOY,UN?L\/>E-b0]m"^:$D&m5aAeh=a_.]970#lT,`a5A]BVThe@Uk)_8 ZpR+H-.YTY3;1>![%_HdMoDPG"s;(hh?NRqHZt"eroGFR9`2OY#VA1#2g>Fn`]<sQ]!,Mh1Z'3Gofp(K(sF(?BUJCHa)%'=L?7gb07T-&X:'n"3`8jh8kaK,]9IG6\/<Y7Q7q;RkiKU%r-d\^d"Q'6c?8;oca32VQE^gU]<0tsUS7LHp?1kSD:$*-:H?mB[-IjN/a>(`5fS$U%Y(qmE"h Vi40&3B5$.\'V/S^Mh$\P#,Z%43m%R()7^iP$oVJV[p@6-t)n&\87=]I^1L\7Xm$T9cp,j7KZNa<98DU:iHc [F!naeI4_E3A15X=K/?&%%JQWN=Hd/_DN];2 a2d0B4+h6($ 2kUAp^im/nP ZYNj/+7+E>\t@9r<sP'k&JX9 h2^2QD0/;go?MKAsS(<&3AQ7?MN=Y(hX9#b<D[$?'MdqLikpX1?<#JAeA,Al)fG.!]CD-s_Ua,+/LCJ+o:SM*^93D*.CY0A^#B<a&mO[2Mq8esn=W,eEtLci30-FK[YQtMWT54=])XZ;HUZHN[`P59LeeKg4<k)2T&qCEXj)?_&HTFo@r`sBp6[,T3LNn:2/3&kE;=g:.(UH3`[QLes6A!@LRj8:]U,h)=/_'_!j`(\ H!Y:h=UA.sclXI?ASLiA2hZ<]`!HI4AtQq4GPikAtU7!b*@aDO, 4?s$+&T9-69GP9Y^U%#@k`7.hBR5Q:s7:n8AetPr3XLSCs)f:K-a9lQ"Z`fqsi0$R,4t^AGMR4`B5smUM"H'B!#]&R-[8de^6X*:Vt]6ZU5(6:*$TNY_9nBPd^4GTS&ejf5Qdgl!:r3+P.`Vf$g#qhm7W:A("#<bVHoA5l^LAN @=:)PE#&1b;LF[G4ER<dT aaN_pEWe=<WidNIg_Cm*I&3m*%k<?.U8^XLB4il7 33F9)/hf*'VOfP>LReJ6M*/8L>="H34g#/NK>Ad1 \CmZ'F^F6E`PKDjC<g,dB]Rn%Nq@&CU_r_"+5=832 /C`(564:VIUVLcC@;G`2qc>)efPUQ&-XD]o?Eo%(9,N3NA#Z[P\rhcrL<84n RsP^.b+KZHk#;\'XYg'knHL3 gJ#doTCiI<lA(Zt`]X[S_4!d=JjP$*n6NPl_<h`MeAmQQQJ-.p6;-8sU]aAG#gl*/V>%XZ@alWl]r/9b_7@0q/TIMA%=L2AbG,3a)lo?H(]!$t&k?)a?b;gpK@tF:H)I5+29Z@Fa8^58D%0DO%(5564 (&RH(!OdYt9-C=.ZJMsfhMR%ZFUc(Y\\5P!gcVp^<TG =d k!i*9tW,f9'PY ,N@rR*Mt/]GBr*sno2/TmHG];M!7a#UT)53mfKL0Wm=+QW=:$n*8;Sc]PEf@b!.7XL0bg,],2MN+AZ_UUA5HD^:%=e,_A3Ep[p/B`j,lde1I74sV2@(L\_L/U$g)&4TH'`tSC2hS;F=I)=i&m4G1eA-$a8dDf?66rdS`Prp!B;)SlXA[N=Lm`o.4TtiFjSS):ep\pm)2,T`GYKK8P-6Bs7AXgQdpEs%3"lCBDJcEWZiBLm)*#P8'!L3M?,[D6AtH(#Gr`5Uc&=XLr(p:$97R'qr 6pH,a+G_VKBekG96_MG(`ps(p$6`)b#Kn*8Rj0Q@<d/A#SmpWSX-;Y+*p<>+5)\]*)N .1<"i-71jr$AY7p7"9T),c)=`S)N*B6:L0U*aW-HDXfsXVf&a<(l/tsMn`;`[l=;f&rbgcDP19ZEZA`M6]Dis-MCIcAO6c+p_Cjkirb!a@hLMC@MqCs2O`]B#rob8S>_U5OXA3pr&39^o:+e9h<W,t')V:Kr#7),^&"=l-iNfP?7jcT;/ZiA"'`s>i 'I3"4N@<qLlApX^qJt`Vt\.\=/QA^Id:T_<*ecck=d0&h/J\hBn6E`[D3[KW!mkdGI<[=!(1r!`NXLXQN l*>\J7Xa=lJE3f( #c!T]m0R<c$:P,Xh0(nCGc2Pk5LWZ/J2$2,aFQ8'$44__AEApbd)#=;YFi4t$aDo=m-VO\_C,=/'.!,TsXFDNePWVRJ`3;#D%`P7taS3N`rVBA2d?=`[b3(.@KRA82@U_TF^+A#KFeH/#2qiXKa` AB/[c?XX::Q4qemr`1IjR]5X`?\]o-( F]Ud8/Zd<1/AeMX7'MXALA.[EWo"A%')ZLIJgcS[>%].V"YU.*=4nA:rY`)W`4sGkr.ZjqmcYC0gq\QpDs<Jq5=BFg$j"4bQ#0b@%nsDE5Gdd6MQ4hbZ,4*F9HTgOPS[=['&;b<tm$,OahH?!AiR6;.8fL<+m%@H9k&=hLI=Y9V!2(p@>/%Qp5h1>ZaEk$iG4ddArO`raj:VV 0a9Co?8!$SI/:Y'1@hY75]?Ff'^? QFb4lTA.f$Yl90*85i)JDM)1n "UeV\ZcL6WMYrcW7"8A=OK YqMAG+\;q"$Q$C'>(S56?>3A2UgAC#$.EH]?mL2VM;j1kO[A__NaH)etB4AY.nDt0PlpQqVNA`@O>JJG]5joI]sKc[gAJ3GibCf`aceB6$AQO@=hcmn[:%9WVS$?\24 o>I^]qF01Sc18 KGW9[F]`I"A$rA]$6Q?OnpSHiaO5_q'XZfnP:UNHje<=W9eXhr+2qdXobd8)-FRk2OK?\GH<Z?V+jY'U!IC6$5"WL;REHI2kE@>PXt\?Wk`3n?d%5iZZ.fCG#MDi_2N&OObPNm(' SW:B8jX`%fFdY+_'f#)B?:*J8sbf$D8f.?<&Hh-37eQOA$E [(Z6"/H`*"%I??Gn<X&q5,@D!$gSMs/ :*&%b7,-&<;A"Bs3CMP]<&$r=Mrl^`$Gg"Pm/521-C>ldl[&$aZ-6gmUAESdC"<mkJ[R4J_rn+E7O4Jf9]atEa!sU3OA]#XlrMJo,JrZ%5d2]d5Kt<MD^J>t`86-WGc'm0cgT?0g.!InTDh,_;?C7!-SC-B f9t$\^.0oSHA94BgE+A2)Ca^"&sN4aY-`fF_N`'<!^NUk[.05sj`2-7AO'WBAAP1.h--3,AA';bdbNhfL$p+p^!7Tdn:k V+oGCW]j[IHOC9Od!>8''4mTaq[2kH70 i+EJh<,N:0<@Z`dsBKA/E:$];\j-9O5#`\Y6.'F4+AAI*L >.+Aa"smg1e-;U%U)M/>o^#f3*la>+ E/j!4FcZM(9RbWR0'hE\*-A68[F_G?dIbeH!+cS<,-m6L^8Ffa)]!9>E;kkaW%rds,W+a6mDnhJ2E?DU'f0OBb[Oo&>"-\P2'Rc!Ls I0cE'nArkdfYsfo_`.74[rF` Hi:9a(?&:SprMXm4Z#nC>I4SZ3Zoq3E3207!e`N7pL]?ALII%EcE)UcAsE.W2Hp;H9f.6+, ghLDk,_;h T&AP("mHq/_[9kfk(L0+c_kI+X[b[n.99_:>$f.%.56=4%s9A%%'/"LZ^Q)EZe,i%eJmpGE?Ys+0$FUa@=fjAQl!/Q.CH2_%2AX^<_Y:3SJ]rcrXA$dP).gd([HQlTq=]p7/]!LO9*@=ca0/Z3@0FIMFf_siXZa@9.G&^+ C Fsf!VNRTJV4"sdYt1e`A8fG#/1shHkP&:Bo8g,r^['#Tg?tFsP%J''$2>C)+>P`r)'DP&/J95^P fLEpi4=G3)34qS:,XGEEiEqS$Qj^Zdh7D/7C"8KP&(1=We<URP`"(9Pbg@B9-_]NJ)^]ZiS^XdL3o 6ns+YqAs/7/c3+Wi,kVL6IioV4,5s\A-jfBCQXt.qR/JRlL9B:]=&[f0^A(L91H! Pj?F^B7M3R:So;X!PA@p0AmW:_R;T!OU=T=I% @ZS/4#E%;gF,<k>3^kEtL4TbtU?mk;.VSrCA$8d\08>K*hJib__TmH4e!?G<KqO6^Ys`b:?/A"h="9(m?NeJ\'A=6i*'R+G(<"4J$giO@R.dsT#icqri$&Yj 1X2L_EbfKJJDg[5=eaGDWt=A>5SN_49jl!&VAO^s"^ PQKL%5)aA [@#,S0O&p]=6,mKq=J,mAB.<#*(_eS ii#NK#p\H>Co*SBDXiV`"%;o^=4VaGiDdCsB$H@\[  FiZ.iALhM>=p0R8UoC&CRV_OUDI5@4>iJ,%'G=Skgt#hMR6H)Ka=91GU[ao9UJH0Ym]S:ZY!d,-1$1"ae].!Ao&h-`/L"ej3YYI.Ge(Qce.Gn*QrSaX7WtSP`PKoVMA;KN3/?YreI$!KB'/mi/ h^$W2`BjDB@9p_JIrqFTq22\`WQH:;")70d"di`KBZOp"<:%U6/-@@T@:KiYlANXit!UJGtk(.t]$C#o+k;:WA&DgiP+TR1r[W2n=KD.9,<_F>i6`85t/+(]s:7J?78q*>>7Q' (Gta[p"f`;AAsNQntj[<HcSFF"iT%Z,P]j/G4lXD3O,ABJ\L3N%PT8_[='i+QhC8A \.X9$Krtr0WPSG`"p8 tU'AJ#e([Gq21Or[em.EB,"-r'+:\t:ZmBb*&( kpA!:63RTsJLbATN`//D$WXRI7,UIpoJ+jDc`<1tVGpW$Pcr#OHRPs6hbZSTU=mkPVLAhL]>@*^q:UJ,G"`'&/)?BB3]4c1p%P,_% +/?^@oPQ1?7o+ppq"@$J+cK4!GY">?J1'-1fA_lNn/[rmG1,_j4oq62Y?^9Q11P0E5'0'3J+tnBlP^]e"0kN3Ekc1WonI9-qsMs@b-.'/AACX:FY190e GgVY!hZ+ Aa7V`Z_k0E865">AW=1Dk^,,nadpT?l,%$1UUUqnh51&M:W,(UFc8Knc0ULMJ`f8h]Pb><?T;qgM] pUNi?FA*HgPa*Ig6rC W*>T*i_Y$RHG5hsO 7bb gM/A5A'5 5,*;5S82DX%QmA5fgNi/1&P;q]dsNU41[#D2D^Z:M&[;0>b\:7jR*e* _H;m;@09TTsFcjAt-$H?DmP*]l<i`33Lth-ObZ#[_K:E1oBKA\U%ZRW/$HD3JrZ$M-%5!t<7.Z0]pM.75r+4gI;5rS?sXMr`\0Dms:P]2@-S@b7hF\ N\EOW*Djph-em`ak,Re(UkHPWM1`S@_8=pfcP8ZF.\sl9LfGbh6r!*fU Y@Hf?V<BLY49;#"?\^aaUV<$#)%"2a4O'aQ,IKl.n;^dEAqKdE4Z(HOgOB@!\-AG7!?sUlS$?.M)&TW25Kia=0F6!>DaNQ=><7L_aC4oAT*BE50p%_nI),^WUrm>77Ah65?7lQMn<"4@nc]oi3t-A5qp*BD@e'&XCij9#C.FZ6\dt?YRb+^2EJtNkB#o$)'-j*T;Y!\55BHQ"*"fMtP2[jgYr:N!ncG>:B^p=+AK+8_oOY8Gd/%R9]$3`o'aKE34?h>E9q%iIQM-+L46?T]4U7`fUoR!'Wekf._+*ED9<%CIS:^tD+/dd>0^3NWop?Inj>Nj[%&qpVWQ<<'dAhmO\pAECmd2l&?<e U#5.)HBCb1A-KcG/MVi8]>2 mDI:dVSc!3[<EGd*YLii!/6_M:1t8>Z`'!%dlD@8pAKZ8!mkb^^kWP[l.[7\C)Ut\hHaj,H;QPBdpohH]fdK?O.A,EX'5g-6 ZS?]! 3rTg@NE1_r9>p K>[;D9OjYkX&b1g4#fGP? @VHt"HUY@2Iso4nIZM6TA]&Uc]!nEHLj2[@dUd"(f(l!VOgneeni],`S)L:dL!&h2`!,$F,=5MZA4(5*0m%#/'iQY 7D&mN=2VB,19(_Rq]Df+Y!\=HGTK:1J?rkOLae^5`JbE9dah/X,k\]:A2<imn=MVE. M/HNTl8g$m;($GkqHs&f$HhGKOfe?+A)F:2^73<l9KSBWWr#R[/#JXY*;&'R`Kk/#o9B;rL?Aj6p8DIeFmGefh#KQA'@SL;>h.Gginn.j+Mb>EXl)Xsb[NNF"Bltp.U=0mq?THM0*nHSblADA&aHj#s#Tf13Jt4@!6NKoK(d5.TLh)9Zneh4)7i=N;Ns?BA5kc"=Hc7gUeX 9spSSBdPO(,JX%a]"Z_fAJ!:"Ds9frG$$lIrib./&@O%f(/`P6E`3T@e?Tgo]rbc*+5IM:H8"GN"j"Ti#37eB@"h44>+B"gCU)eXFRsTHp[V/&a QO:W<^A$_:tU<b4#) Vc[$+>[/0"2>T,YTRNY Sn_@0#m\3"cqBtQXY'?Ial2BW6nhIA\cUc=c B^!d<XT^L*`eK"'/$fD(;\=]/OUWNB>^W9^_-2_/qD&1#nst7C-&W03D>ah.%AU2(Je.AB.e#GZFFZRP_GPM#E dNaY 0VP1D8d.hL-%'UnXRtLI@YE"@q"QSJ5*<S6HM31gL;leT&,%CIVCA<0o!l%V+.>.<l_^.0p59j-c,/D(PGX];F20MbqZS/71H10Nb jUpp<,XgB: 3]?!;]nJs]66fbIH^W@Q'>1Z&LKison[,3VDs[^MEaS]Sn[35_.]M@DNso)?sOc94@$QJ&533m.$k%T[B?%5:!;D95dCA<g8R\ U\YU67Z/O)%6r\WpY?+3RN+$c] 91:cqN'9s[U?I3^bo3"Df-2+&Zp*=A$O3[kn#a>t"f8(M/,$_8@4Ng[TBACtPE600l;0IMBA`e;JD.6+d_!,C7X[3Ap5S+JkPT-T>@p*HfGgC8G8l$Gt&;j qFHG47U5rP;'A(8RiEp@-"gq85#djA?-M8U8l`BjW*7"o#3'\$dI"Da38TRHP=P=b^Wq0LaaA]%K'8Ykc<M'RE1.ZAK=cGBNZ5Q-ehe`7C/AZIBB565C!l^AsDa-_H!W:e9"//Q23bDZ<7<N;/8,s5\C;]dA!A6*5F]!R1^_(jVVN>HJZ0>RVokpZ#)k4 $Ta( E*Tc`dt_L%h2PhE.5Al1Qj%)HdAUd<e1Cdhid2]iBZ_)Y&3(Vs6!.kH\E?X;EloK*@peE%tn(n-8YnqG ]c3_ 7];d4;IWQ8\2NQDZ:TGXQA<7n,eM!=OH6N6Zd+`j&PR_??4^pH/Hk]n_*<!#RjQ_A((2N9Kq>@.S4R8'+U'p172,a1$&m'*N+8iMb:A&]<tDCi8/#cSI\a9V4ai5LalmGl^ogSk@o2VRqGG\[8,@&4;kt2O2%qgLmo=D q;O )14-B0dlr>JN+-=Ad,"N$NbM?d9GjD's27\E<@s&bG1?me7&qFJjE?g)-^fUf(SoF1K_\<l-"OTQH`-+4UJ_n`D=m8nTN_t'3(Rm!*A@p;=5oH"qq4B[O;qM]t1UF#Bpla1KBSX;K;<?]9ce_eYJ;\1'*I&lp.jHTAeLc9tI1g/cQf4D_mTP2_lsaRnesN;UcM%GQS/Ctest/sun/net/www/http/ChunkedInputStream/SCCS/s.test.txtaA@;pe?>W!jN@`lf3h*-Ud%8Ua!AkXGOL%U]+4Ol'!5J)M_!`X0/T1,N^(.SC77FpSiE_rZ^N*g5Ul:XIks/gDdZs70+kKtZ/sdg(l6mE"akc.1'.6) OI%<l`Ea/YCkJe%/+MrAndHi4!CXC>Xoka[%<;iI!q<$n0[X\X)sJ>:.4trHQF,< =UMci)!lr1H'8bAc_m\8W7C0[fP`^sZU0W?$$.%XAB5G<%JTq#0L7OC#F"3Lb#eC?XB6:[2%PM;S+e6!8p[lA*QK7Ci6E)FZNRk'42FmIK"7$A NL!DG0!ih`'L'-@jH*PF0+^e$4336K>LoV!'YRt+!IpKM5o7&]JRKrL  qaLj\W`;_NT >)t?;[?')A\^oa518(VaT5ifW7i2_DFA=.XE-R%Y+TWiZAQ_**DS@<6]AtYN3qs=;"t+ni@$pS;*K)6BAta'lcX6kMF2Z:H:<sDr!kI2UsDG8"e&>].7)+*EOFhSH4S;R7:QU`N>c.S9B*o6^F01lSo\/NX3nd:7>9Nn0! 1Jm7<hl`RU;.M:_j%0I8 UQ"L<++5*<OgN2i&ckKCBMBP`(i<rapC'm;/dces:fHsZ"pn;n_R]e!FDA\Y_1CZ_j8_ONkb3AJGAO1)elqE_ZPp8E0Cn!dGq#hqH[gf:t1=al_H#OX.BS0)`te92e0:.1m[nN`/1Fd#c3'6J(7eCf8g^$ttjOKk'fiV?&mR%jHYc[teB#73Gp JFp<a,K3._$NBH8i&<?8dRR^?jh*$3?S'.kmCi_N`4'_gLkJ/Ag#gl&3L<i('OhGXmgsC*?$7*EJN('mD2LM27N9geZ[-nAb\&:rGJ;*+h6C!tp$Ys("dEZUT3T.79sh"%Loo[c3ajg1SJ1NVnZsd/ HoFS(eq+\/bI.&ftd*gd[,#:;`Z%<M.:4&l1&aY2?'_A90V^ahK8W1P!*CtA:JQ$L417:&]g;nnfo\`de080A!dBWZ%OZa^1-@&Vf=(4OSm'<XVgL&OUi[&ci(R'<G0iX&V3.l.a+D]'p,cJ8El/8A%_8o)#3G#&F88V1WZ-)=m.D<CGCrNMG[CB,m2<\1%6BV10q46LoQ+8`LBQi[_sP]5@cf"=/3]]0$&+3q0pF([9(%bA#mm]fR%"$,Y$T%JR4T]^p=&e5r'<H"ra,j5T W$opW:i<GJ)^6s2'oE-W'fiPn`aIU*@G&KSbM*NKAeFjf$I83:X)tL*6\4(QjqO"F[akAH];)DO&7rETrNsR_MRBhNM>c8X$<5`jQ9,r;qNsognA[a*D2sp5:J<P#?=K<pO3XA>lS@D QI+phUn!m(;kKD,2k+b`Wh\M3+1TY(, mAs;!2;NTN.U^ /L2%D^'L[QT2Q[;4OJqK]Ck7E[o2IM7CXBLW*m1?#s$* H"MR[3R:[/.gC\[T!`2h0oWM]*&K)&Z,Kh(JB1&.eHq!N[M[AA$"Ee"IC1\:j7:DPn/h):XZM\OPG)o],.9]NghLT$DA#5Cl+I# V%t[!l9GmT;)8AOiFEXoL^(2'AVZMN#>0;9L?,JF(gifpJ_*pOHQ3o0:dC>aAU=kJnrVq_:;m5r9BJ5Y)df/`3nlE-6e:^i!!7@!b&&cK24pdA]mdr(%hi@YfJD1YJZ(Ddrj08G:J$iR%o\o@4aVPjB0h59$ek;]W)hK1B1-(^=.gD^<1Hgl8LmF9M*e:B5`Zf9!)IH%8(l +VXME\Bb>IRe8JEQ) XNm9A8j5.Doi^+%c&l;N$LXq4]U/fkm$0$;r.q7aX3)I\b[`RhVg\&@]Q.n/>g 70`Ugc7pRQ*LplB&QOro5!!g@8HMZB7@,8RtoC01JED6o5:l_/e'Q(7hal>EiWOh)`KnQh+h?5r912!?'r5'b+(Y,[Q'#='!H\( _`CBR/d;`6AUDN:%d)@n`Ag[,#mPGYWrZ]7?(NRG'Cl9$oCS@^WW8fL#po4`[U7&;&#MQ4l9T.Pr902kA!LQ<N+o4/=.N[=@dpWJXQ(U8 ks)70(nRiF&HE<1<[YU9Ef/ 4+W:0o4]OUs%@tWD!+Xe`%CE:J9;As:KGch+ORBct/"^#oRJiU(*iYS`%]_M;L#8f$N!*,i4DD3ed'P_]VAg4 oQ8QeV.h4t(=':Oc,JYWD\Y"?f1ML^)$oh@k[O;AjZ:Qp[\/LKUH9M1?N`/J"?Kih(RN7J.$.]Arg5n;_M8;>!A026pHaLYmq2=C"A%pr1rIoJN:ZnX5ejVhokNR_#X;5h&]m&_<H) f,#*!tAX1%mX]W(\%!('#QAFpP/nAi7U8Z$"3i:s"2\a-f r7D])pAqsO,JJfT9PM0f$`96Vce6jT_k(<Lj#$$=G\U3\gS1A.9=K=#\+U.;SY)>Ckkb39/GjZkTm)8VkLZHmj5%UJ#G2ngHtb([`WTN$Q+33HbF]qfKqUmRZ3H$m9l6*G06>+h g^<fc0`X7Y_\aNE]]X!`\pTN9=t:br\LS+kiB7QJV=NV[+E8H<,n\B,*N4d+@2ne+A@ )fq4\\NZcMne*\a%6hFY='!%ZOcneid>`NWdnW*Cg4kkkteOf*aOTRrN-:\e#%2m^87^1[J9T\#&ASQI9[O6gha2]jqa Id?:@^8]ANc>@*G&.(W!%J0?U\FJIrV&_CKVR))Gs@H=0I4<i-`B<OGk)K6L*"Z;MYqA+n5,0Sb@P5VLoGcM+/%\_c%-+B9,@+pa%R\/GLC2 _'cH/oj3lAP8lDp2?C.X2.9Vh05c@K8m3/:%$XI%i.1jr`8(rRLm<KK9C=5>f]-MhcM';9"l;L>dm-)P9fUJU@G*`SE?AVGn>AkA &gtCe`Q_-Y`I@AZtkJq!oD\aIZ5H(X;g<O5U]Z\hpOjksfb aKpH>9K2fds^;SA%_J"<dnF._00$)+VG:IR:rUNYf*?e\0*KBfR2beA&JnC7n^(b[*g'ZV^Ah70:!+*UO?pAPZJ A82GEHfAkI%f=5*?`,-<Z+*@k]F3=-<O4lmie(C\:#n-OX#+-l3ENgb3W=88A88&IhM?H<5#5:r?r2f8+WqQ?B@*rUV=DW;<ARrQ\Y)TCX(j,rPW8T) PW0_h.b:,&>Eo*"F+F41H,KleCP717"L69Z%5(Ah*j%:q?HH.maa@to2VqoQIm!5CoXk&"Akk>%/['&bP\X']n-A.)q$1OA_9C4AqpW%f`U-PrC< M %6DqGB<QWm7X@O!flCOt_B;2lmK!KgjG*'Z`_.:6_9k:-"ZV?+KZfg$<EYIV<'s"&N5<m6ok"iFNPZ3WJA1AJ*A]#Rj&pC=hQ*?2PX7Og1<B7_>\_bYLtdAd)L$+4'd+6K/.:ANU.5nk<5$9fSM+,PIESS]a'Fn"=*qg5PO-=bCW7EhL6/1.=hgF.JkE_GPMLs7/2WhW#ZYGLY\Y 'UTr;M7Z[\e:JIEAEjr nisP*ZAD%%X5<U^UZAQthgV]=YG:R>bLSMC`_0Vg>hbD]l@8Wj,;CX(K&3XT%tFR<>F)'q*#R[bcS7Rke'E>_6IV[g83]4@QT,&,. ^7K>nL=N'[,Ka`2s4gerT?c1>+%+T9E6_""$NjT-]_A:C,\O!<H95nQQG>N)oLJN+cIh>7M9P;I8f7L:FJ`h[$88Z#".tae"1(Kk12CWL:mUi@[/R^6[Fl?`m89[Q'7MIKRtbVtq?jZOWADLb)5LfY9NDQlo[I'jbtm>1#s;n'F)J\B&X$T!9sH@4@gBL"KZZ3lpNV*pm%E,i]i5PQY]K[8M8A02L]4.P_8!6oBbT1e4U9s+LmG9BX1a1SoTJ!RArs-M+4oHkM kmbd?dm^IE$`>fCid0I^j_FA6VAr11+Grl$h=>6ptU>V.D$-Go<;AF@[>3j)B^`8scNE>>Mn-B>,d"H6>3]6_[`pbI Tli@StiR;]&^BmL(.O&<D$)U'*n7+D]7<Q :G`sMgokVOLI[nq#W 6D4.1%<PE/@nAYlgm& 3hAt_NHU&NVZefQREB6s),R:I% d_;.TZJdm3T@A<^1 >ll 7T:H4n21BRe?`b,Y9@G=BC`3%/f8^#S]K,AJ]Cd>%tA?@JhO+3jjb6mg.[lFKH_N54JI^7n+.R9()PAAj',,kea\.,*heik"i@KE_Wd,=KmhG]")2:_[JOp,G[C]tGs-d=!_7L_p<MA5,rL]jb*?p1cq:S$NLHAn)eMOLqiI\PpeUhSl(G^-4H`WVCG<7]Vh4i!U_Z>b\'kZf$1I'2"0NlS5XXH\hW0+tL6tIa8gWqDQa6SWil*jk4V31KfU#h!L-(2kYC=6RZSMKj.M&W44@Wikh*,8+A/k=b8h5/*O^Ei T.X=b?\bmFe4p =Y\%/5Ad:(39>AWP#ASmINmgl"gP8&^icBi;B?3,qR,UdC*COaV^0r9^j'J/g1'^k gr`W+8\reRBgta9P,Tao#^njl!.aR"nT:YQMp[+;sLi9m?"h, J.7VpH.?LB&'75J%9JoR&iS@9[rK=UldXCCraQCD_O("f>ahCTF/-Pq,e*QC7HO%sAF9-@XEV5QAft?fZ+]j6If9?D/*Xq,>H]8qjGaZ,4coEai+qPAnrsoL5!OCPl#OQ2Qj9SNTT5r=@-ghrL#+Z?)f9Cn\^+VT4['%"0Apm \ajn%s;She/E2cGUe6S7HifFtC\C'f$Drqhgn6BknpXP`&%lOi=t-aD\j.X/SAW)7AIZG&UWi_(%A! I9pLp8hgsS>;Q;rV5oG9dLDI1=[E9K19`__]/68q4[nWZ+J3Y0X Xop\8bDX.*#el,[HVfpa#`@JL-`dp)[Tk#.:sZG[J>9<e\W=5V,lnp4i,<g_cmqV2O;)W5R`64U^=Ad`f>P$:LU$DZ--9Sk;"PMja,,b+r*i@qMY*07mWpi@@c*@ G'%setr`Oo i$*<)K6UY/`X<tP2qM,;.An2aS6=$B86<"3\3!731(Y<#tL*X0[B+#BEn%F6lHP7/K$p6 bH.PBt=V"Hj!-T_ 6@Z=drG0j5djnd'BD,"*5],!!W[4epUO)E7\jdeYUbPAVq'tY<R:EjX0/EnMLIUffM0"TB^$XPVSGNnU5K9XJs-4JnEsr`@4-7931N%+\gAh*>\3./4W,<S/RRGEA5o)#Z6MSgW<0TQ&V7f;*dNpn01YprAAPoFH=&1Ta5([9[Q8#D)+Xq)AAqE+V(Lto<RfAJ,e4/"RCUgIcY&g,:IiCP&i]?p>cg])P.^>ENU4ZbY,p08=b9KW;06emM0r2D]rk7*eq>]UYAQC)68bl4>opCE\@Cia?Yjh'DNB5e!*%JLf=/:.eGj+P4?DC_Om=IFNsJ`Q,R`E9*te+:d6sR8O$k?=rhKA_+]7Z]$]6aNKc[mmE,:FtHn"Z[SU`r.E6a;'n` .6L1QO(!JhXaMIO@+Qsq)'+DD-5?B4d$!Oqb!;,%/c=+I5tW,Oj<^a?%TD:r%f_9U]1t5js[JC>f&O_cV"rIgiJs^,mD?<?a#[6G(U4b@q`T#6eJ6.Ab!M3#lmO?hsEZL*(dkZ]c2=tLk(,oE6jHZt&N=UMKf'-,$$)6 #7**I>g(;(_GAV)i\M)[#kW''Ur!O*kP57AnnHY7[47,R[&9SbcXW*BVr;=mr8+_U,nUr0I_r^@ br^=pAgHqka3BEOph67]1U#"j3567IZTC*`oGdO21Q3l/V:m7$KdVE;bV28[Z#G.F^&cISNhZ82.emT>oY/^rs.//X=<$%]BB"528)tTn4ETK _5C_IZm;"&."APR@,;=JGk6"o.[?<%Tq4S+9WO,Y:aB#0J<DfKk(5b#5sT<s>LjW0#Sm(\nr`o/sP3Ql%&%j&<>doic^smX8+27 '4\1M h_0q6)99eo^tAm^GH!C'QF`e5r:ns#*bFm7-:1 ](B`E2trob<6e`^FeI\XUA9kMIt0'M5)T_IoX5pN`2C*E#\2AcR-Ns<Np*/%X WAd`q_JP_gEEM/1(Do<C8XgY#Dp<Xm/%LQ"81F5=N2ip?Wgm>d+ pqo5=;0JsKDQh+'kN'%;"o%:ChHIN$R(KD5)A7Jc[eHBs'!C1>3m(-fGVYj$ZiX/Q7HArA'Mn;8r.W]i6m8/f,>4>XB@MJ!Io(o'T8A@s(?h`KbIGDOkMW_XCee:lL;\#@1I:YO8,p&dMm]#h,*B[o;-E%qUt_O00%l[_BkDt,Wkl8g\6@:S#a302_O>dZ>*>8)Sat@-\/Z)ds3.<cK]r=m?rMJRU//=EbSR$cY=SD2([/I/X\8,[noB[3;ors H$FV/;4C":NeS_0Q=R$^cai6:+r^/&Yl?BQV,?edHXV]5IkLG/CFp[19UpnD9sA=ALs3&8WJH-Y*r>t6]-a:eLO/0_0tPT-Yen9(*eGfRT@F")SfYnV,$?L>%q,A7NT=/k'oh.kI9f.4kQK S(%_X%`:"%g0/]-iEm&[U\ARk8N+U3bl4(Z]G$9_d'hbSoK#bYreD-cQ"]W1T<lE#l1]>26F@^WsI QV,cpI.<WPTP<L0AWn,X.8N826l+S`=o^_M"<<ALZA/7J`TA+CmW%=Hpp#G.LQQ7,-+d\X_;XKsIh:V;?^EJ[CgDO=W^d5[HJX^sf<MV&9^EGckgbcj>iGi0/^_H5W^PS<eaIa+!`I#',0+8EG_45qFL6`VqR<?0'<+9K#6@b1iV5lT=n0;")M_As1G#6s;+SNtAoM"@po5<'RV))KZnbo#=h7%Kt1C9glfp7QdoYlP#O5<ne4nA`qaYG(p6W#-<'koFtAo$aZ/iWiDlbLFj)hl57(eVgAqV:r\VX@J7?Q2dK#4JmaK6e[AKpS\:Yc=Wm=Qc*a+n=HP$8Rca8V4""'\Xqk]Z-(ER'AQhAgs'qL4b#R4#dfJ9ZI[Ml^+ V5Sgj&!)!e"R'qLoig$a+22Xg$%Ha]aIbfPgUCH/Of>etF:UY-Q4GMPIg:1N-Ol;P#iQo3i4CE.]eYi!b.HPqP8?8rqMK&)%ltAtt7I[2Rc,.F3()Il`)9B[FH0NMiF"imOiBAAQm??^25+I6r6eonS@9&nM5t#5HMGTm&V?EMn(#^6B(X%X_4*o&["<gpegC;NPVl<q!n^mh9(G;!9A44i$aG B8._?n.9Kmt_Zj3VmR2>iS<lhfLWQ"r\(S.,[FedA P[:eI.[7%1=F9feY+/-pqX451L:lO'FDF99QQr3 N?7)e8n=JR*B9fd'CSUR],Qm`e@9#bgTe$TNn;aV6#'!Fl?D%QIa&S7'dg,JOJDlp@ZBl;Q#_-Tg";T. AT#NRW;.50QJIm9aZglf5YlG+?*"h7hZ)^Mp $`9&<2X_i)"snl(JEW0[4)D9A*/O].#e!*V`YXIe<;[*W !UY6+;+gMZ*Va^Ik&Q;_`Tj+S9S2b86$*Na;?ial(-5HWQA'T;rp/kbE/#9>mAC77R<pmk,dTJbl*l+&Dt4*$5l+L5Kd@W=@@r)"YYeK)RQhDhAWtU;jBHjg<n+XE(-4#rZ/G*/Ykp\nE;kb7JZ WdR86< 8.V=_O<HcE8cdW!\\&VFIM=K9)ZJ37I<2SNB,K`&9FOIdcZR6/@-Ykdb-hXdSi,5[#gb(t6Nc>7$h<(k9T(XHbMA7/&C:WHXsLIsj:_JJ*Pjpe$sh@tIp:F*]"#H8KFR=QiEorEFC2VZhO'(\4^C9qN<UQIrXifg19elc4/Ebq;8^U_o9Xp2_f(SMKRC<8Y]#)eI':0-CiAtjdVV#kZ%!3Ja3UftM%_[FWt_ =*X7()b^A7B]M]dog.cq;b56+MLVUB,fO0<,>Qh,rjGm8[JAmGAC0V@=G;mMLn%Va\ZK>niK0tYo9E7\)kK\U<#6(oX1Ngcf?Mo;dB`lpDI9fVs2>#Hf>LXnq7PtYp[8>:NaCgFI+Z@#As?kokS9%.00\jN"UP+F9*5dQ:ph\)b]Lr*Z:E)bkl q8k1L3mKlc\70&ZNfp7Xq&3]dNg@[T3&/p,id;XI54:&`jOVh]U"Gd4Y"gq5)\n4f!TN!A#lCG:4NV< ,%p`b<-4q\dt^n8b&lpgM+dc/HXAsPgFABAakW!5h38tHVne0prOK@GV+Dh;.A1#;WF5Pb &)A`Has6C#0[TASJW&\8JYpDTHK3_DE1RTlPjRrcm;G&I88C2CrFY'Lf;8c&sr&pBrTSsN-&LTj%\-ct[k^\Ro8JPP% J;Pg]p&8C7`CRLg:cd+T=L*p9VD+'[R$EPM"iniN=s(57WT0eU$K:l,;rATGAKKE39d=`!N-VEA&5[b!MH?;.kKP"XrkJKa-\kZ[SLD5VO,Z+J_lNp@2\HE6^^NO%l%+D0^c9>j6D<\'V;;6[8hd4)2r@\">!pAjXRrKW_:hPT*039!&)D^slWa8AVt35M?6^?8)XTqI*9O9$SGsX!cbr@t!.FSnIGf"_TA(FO)_DGr?Cm"*'hhOkF)C2fiNoDP8YCIkA!l0gOG8bCXsn.F'3=9#(A#r@K@Uq51k=@_,Qmf4;^p7XqnGH=0h#]p](HJ?Xj[>r>?U-4ZH_iR3c;LenPcIF/4\*.ORidj\:Amc]oJ.XFN-<es"F#Q3IA9>aNP")GnN[r.A9qFK;Uc;f<$%X>U+eU]\#pj=Z hqWM:MTq$/&N;eS&<8TLd:&Ab*r$I`^Tjo9Vr=O)->.eWoX67"jKGNfFA%?q-'EK=8g'_3k:PMOEKE66cTU99+#(D PREH#Xer)2ZO_:4H:'/d Hp!I)nqOrglfos*[lJ#rR&]ShTa)$W;ZKenVk`)S[8@?B*'3dHLh$9&h*XmqI]Vk#@AZ"RV8n(tC#LlbRUJ?(hjnf)ZtlUY[ sgHsHKC%1nREJFq+@D.nb4aA!9pS?c$#$-DA*6GQ568LTrtQOT79!lk2d F<V \=VL),,A*r7Z`\M8Tt-h6b"kK0iYt<3jNM1@,16$2'fZS#6XF?)@U 0paO$6SGHL?aq:nOf1 F=\]]8HI1qMI^MVRTRK8:rAMciqAYgWp-;V<*eim;N=!c,ICQf.5jD(U*Q"s9mbb +kppVO`fBYCr%5DOEt?.=8dQ,^JA)po"`]Aoc&dVOHI"D[2ZQ&4LUl:-OA-LG.k^Yf0cfJJP)jBF]0;QV_c\^J[AbN6.t,*Ya"nlm,m%$:i(LURoO=R7C=*pS=!=:El3k0PA:!Q2YLAiNd3OhDTX>Po5@"s!WY7q`=s1(Q^S90M#2I/3pHgkr=3IlK% 1r\_'N\1cEU!;668C<oAKN*1JToC/'IakSWG2lc`DA5E ^eL6(#RcT3"c,Jo5EJ&(9hWoq.];E;6#Hh\l5*es\7r5h`O*&,VFX>"1-W-JJErl:VNKbji+2SUDcdH0\3kh>c26a1h#6$8AV3dCAk<5EbS1Z 4`1CE7a7ELnOsLFXTVF9S =N$7b4;a&,7cUY2hr*P]nX06GrASL`<\03eZ*[lG`_k`i);at3041D"Q$`9L]YVZ)Im)IX<\62,DmYMR\HS"t?]o1:NBtH=[:>b#K&Y,$Qa /sl][0 &?pbqX>nU?)1#?jkC0)^$T;OIEGAQ6RT>Z2+')DgKA232na)2586_o1=A>?mBk.9\J@isKbA6//kpEdDbA]pCoK$f!%#?`e;Y-;d[<`&+=XS\&VAoaFZWlAJ#N\)4E=0tMCMKXk$6 Qd<#5@rNCh%7bQeAke(c)Vi0bEG/"8`maPqA!RC6D1 ZH8ME@A_[flBH_CGObF\AAL];j<a$\sCpRQXhFHJ=+IQ'Ap`NnY?@dpaXiO6'V'9=]XA:A^a@dD&9$;GmjRT <5BcG=72X#SW_-jm8NZo *bf$HDJT<F99b[a`]5`Aqt$%lr0[-IGP1m<L1tElo@J567#/\[)q9J!$q0RcS:48tfhg\?8I9B)bd)qqZo-;O$?! GR6O X7E[OqO++"X2oFnYr5AZEFqSNi!MAAJ4>_@Wkf?hM25%P6&fg3/0&ZQYE4(ABStJ'qKG&=YQ"A=esLc<W!hKDoiHFYa3?9]",+Q'qDf\n'qF1*Y3q%.C;,es+'SXd^dCto,X'<ZEel$Q1kos$a(n$G\Iq[].13;`PA4'qEA?X8o !Nn0!e5D<`m&GpQf?AL%/iV\WZtgl4jrC=(5eOQ(TAS9rj?5%,]j3>a`BO5b\!,Cs%U5WTM@Xe@59in0#Wnl2CGU/f(I.nnh8d9nL:.ha],dL%!O&(;Nq5MR]r<pR\#Sld##DF;Z[sJ9eGCe1\I&V&qCqEh8h*ttJpT5X2eJEi(Kf;)JQ`%AWI4g/9.*=?H?2@3-:$BNSWXGXdX1)$-fNk/7q72%GgVXc?7.%-7` Cg2ksnoVOp#K0K1'N*1Die>N:/Z;ga-Rd_JjKB)*`_4T'2AY=IC:d./8@WSU1) [8s3E[W#gm#Y]g4;[r>XD`LY)lAF4[TCgf$-_4' 9MH"I=N+!+g4q:;4m9WI.n/0dm?!6mW,,C==\O0^I"PPLZq2b^J$q?gQG-16I<rW'6]$dII283 UUW7V6D'[Vc)la!]N:Ym*K'^0$U]RH_N,U:]fChQQ;\"8\A.Z"\1-!mP#3P"6TY3:Q]6Dr:&6q:N9lYU2$QEtY]fR3aCR5P^#hO4:X#--91cW8Z96HVZ$A8P'm9p,8-2_R-Wsh2Ckf@4+@Ys(UoK@*CE(U":0=1OA_.Rqn<taYeNB30THNp#c-7\ZZSdGK>WAdHt5a>4J/_ls R#6\J5$X]o%<%'"3 `A*]=0>+@dhpC!UWb>_+;@E;ka<HZKR8T*,"<7J060U">\a h9Y9M"7Z_IET>)L k$d<W#+Y-)D,lI'Yp;_ACgMEQmhQWtn!$)&9m(F4VZDP0nWM,;dqgGt,rFM!A[#JCK!gfSE(h1im]f9lW7RVa<)(th@re]`/:Cgs>bAaL9]AM>As=oO(Pc-D5@p#<'NM[JQqZT[P=BLtscn*t6C+EYZ_fh0QSCk$LI0(a&`:jtpm6^%=L?8?]\F"P"C](I*(^fSr'$[gatV&o:&k?m^:PMi.f?//`>jOF%`N/ 7-7N>d(R5l"q8=<L2b=?Em0OkSR.3"\rG:o50,sp0GhRrS$)e%Af1^11B)^ER^@mjZA2%`/T]0Yq<A8`;XtM[+[,\S8"[\RLH/tc[<%6c mrAN"CkL=bVE(M';(5.Y&76diNr<PDD1ik*]7sprI) ] Pa /l.@O0Bt9-G'N[I(QGYdRt3&Gs<QgCJQ'DU\OZ$[8NVro_<T"8dt=Ba&\"MjJT[&ZMZ@'7 sQ.bMcf0trcH],A _r^A$p/*7\mZP"*id I>D^C0(-M&tddJCYL:UdMj:pZPmi$_;/0cb7H/1?AlmR(S62#F"e,&CpSQO[m9[-,&dal@DWZ.7+H!;etAsatJpZg,i*okI,S;8Ef`rj$F-N\'%=DM\;$jk (Wg7!2531OQ;Sj$^j^m0jU%(l]j-e$RGirG"po^71[Ie9h+(OLAU9a D4e/HbsAn<P,5@RG'M:#g/eVa@<@L0,(7)X7<sVT&,R!0V*3c%Z8tkS._Io(Cp^)Tah`r^6FdQ T8p3fXjBQ82bbqh8FNC`L[i:O8CX#c7&NA5p%Ph7Fj=Jg4eTV4_8^fBm.:L7Cqqb^>e.d%SN;;goAQ1_`SV 'N*3#kBs 'TfNp`_JsMp$VYrcpIG9C+pV7[j4d,5N^\EK.q1ff!AU9AQ$44B8T6Hg=T-E%"VjgbM%dq d@13`UgbS?#6I$pdl=Qb"p1;A-Q]0Ro]bA "k&5G(8>0`#6)JtrC;_hdrU@CBBrb'%$C=ohkmZ0Q[\1a4A'8l)nA&o0#<TM1aXEGm9.%BqO^dP(H&?q%?'FKQ&Y0g];8,Y-5c"f<1V.t(%#H:;ek!imGA"`(k8+.ak^_CUl(T(eZ@^;sf0!saTpj)5peDp?ZE8?S>n'=3!iZCh-<:f'ZOb0<f&)cZr,!/r-]^I<cQd7FfbkOOQcmX@p`^^4;%OKtX<pLK 7s*r3W)kWFDn^J sjIQ4/^Zj=&7&Z:\&+\^%4-5bD^siO^5:&F9d'I[im#fMPDHhVJJTpJ/sAabPtV85*Qt2`_!2GePMb.g7E+`D6)]:dFAYm)>;C&mAF\[7(f7=KfAhpjlM7RT)%=jrK%C&I8J2&E8,+c"mag3<rUK6+FR@M'=@L5g.t#$k9Agjd^(-I@C7Z'!e!''k`[Nl'km5P;;#i"OfWWtNVPKpZ+6QS%\3l;Ot;d+NM,=h#Nn:&]UFP2n0_>"re'""-#rrA?O _0G;KM2gQo`HheqqRGAmAm7"I3r2WYc'eeioojXT"V!hZ3`D\Etrgo-O,VaX8UU_#7GiCgsXV%-PK1(JSm7R'&eN$kQ "#kUArkU4lS_VQ;rVsiQ &@A`csf1E`*+EjNC59F[V\'o0$#Rhbs)><^/Q^/bqL3Z3k. [Umki)clEnQN\. s]S+8ZF0?MBlAqgC\[o7F(1WQ CkHB@F>BU2f2Z>AZ694KkP4q;tkSKaoF\RJcB(+-92"7=6Q_*$'[h>e9W-2,'"E#:D .TqXm'"HeM?]3-jc*(T *QET<^]bb3m-P Y#-\Ql'WL\X5r: H_BjbLsb9a4N"Eb/Em)"hc2XLIKrp.QIXGDL.n*X5A6:Iob=-6k;SAQ_N'>e#C<DAeL=8_GZQTE*brM,-o&FALgF@G^i+HRLB)A=H,.(U5tW_"F`>\G?BtOAd%r'H8aX7%5C.5iR.`,Ng0CEKL6_:=UQ7F])d6r(Vo,^O6[I. IJC(Z$kS-sBWMT(mRG*::NS0$Oo!1O<e!7hE:R9hJY6IE?as"^YBI#/Cp'9YGW`V*c>`IO,&)k%lQeG4&oQ*2\aPM8]Fka(/AH508dooZB@\\I\5;iGUNH^;S]NpcJZ>j!EF>NGe<i!2Fr&"T\cMiC@K-h2\g^pTTPl%X3Q#2%t7H/cBGACb/q%>rU>On@+&d"5;;Lt2A=N;$S67l*ZT@Q%7A&t&c[&04&C]e3M;+!:k&ZpA`B!oT$CJ:IJ@Zd>ki/!2_-9/'mki_alD bhQB,nUVA#7dW^8EB8?R[o.<B^,*,^7%lf.LEp-pHD>T(A5E-?80 DSoTFEi0<plbV]/C]#gTHPoP3.+5kF/KeAOUeW>4?%h1h$HL$L-L=nTrHlLAj;q^A;lL1E\XL'p/B5/@9orORMon>Gmd+6B8_r='+MABWfsqL:ipbmcc[lY!A#^f;AS\(\;inAR$^FTn<6%'<rGA KY]PqQ(B CG8km(^4*FaI#9/AX5dqWkn:)DM5eNn.iLnl>P3dckS&]nV/q-mpOIgF-6\kriesO&TM;<HBX.]iUlX'D^.Yn,HQRL08N9l7)9F$,hop&[:;8e<`k4."P?Y,l8C$Ql"hCsEa-8;e!n':))D_+qCBYZPDk0hci5ZoNKr$t5=*U[p2gr^\Fo[R.]T;U7V7''2&N*3KSFA:`3NcmBr %A"%4?AACV9YH`H1p]3S]Xk%npQMk/4%)t= "rRRH@o)9g_Akhh>B9hX.[d[>qbd-J[Bmfbd_/j(OVKX83N8Df"4JX^:CH`\fT4,')p$T#0XGfAqY`i]/rm7"PNQ[e6J1OD#LH$QYMMqH1%QL.[tW $etq=r$F=YA^L>DNj4Y.?_C?+2WppMb^:j!.=gl1/<Pc"V+0mjfYF_<m!0t\N`k[kSTP:Aha n/<3#"2[Wi'^?.r:I@!Y8P< 7seCS0OBZ9](A5?s)Gal-3UpJQ**nj.`b^1O/f:*HG1DoD?:36F:*D0U];^Eg+ PR(D)['@Y;0QT4L>:?pBa6#tZltcS)R58;MR09A#p!Rm%RDaTT^"o@-C@*%<;)q%/4.W)nB7^SrWMB3l>$3`UfoUkbgRW>FGK$M7c:gV6G4cWcj(+&BXnc]6Tp+QP%.RW^'-d3Pq! U%l'j26D41c H*(gS3NiQIsa]$Ion p8H3nr*>A^qpl.W<mL*:J.4RE@\g`HXc)go QcYk.T"QRlV9XA@N"ei l=HN</:l,m>[6)\-o+RU]Ydn%s.ON3@Ws`O1<TUEH]Vc2erbp.GYs"B'0K4__8YpA=E6+R1Z.Ad27;$!T_L\#7d%;4c-5T:D"!4h7koX+m2,teAq/H<]bBH&@.'hi.g8J[?o1E.T ^$::r:t&V'oE`)F$;jbOnA24MY2Q59ms5qYI`Ai`P&]'V]fhmi6KT&ZO:1P&eeUZEK+ 9\-00jsAegg\+0;E+F)_A*ptF,?,/dVZ'FW>*qj/B5AVF4W/-1!ib\(B9@a^gIpW;e96\E*d0'bmpb]\1)22,D(jn1<Qme[^])fZCeD>X?ZEglE[U[9;%D^n7Ad_P7)iAXj@tOFI[@4=>>%[g87r8T3+Pt<)4)5Hh>ODI>'?5@APJcV&bXH*AY`<T$(Rs)a.+K"EHpJ^-Q=1pk mj%](g\9<>#L<4`0ef;N?<EECbn]Ub`W5%HA?):HA+_+cRP7#fimbL\e5SsnXN'Md*m&1#X%1?d+D6pNE`J21s*Son<O)i'jcnCKA$("p+%ZBL3-+:L=1Uhi$oP60JN)T@Q<AM7]Tss+q_V.d+GjYG@[9+D!G+`jS6_sHq]M-acLOb3+*!_gqp;\5Yo/P"joMkrZh)L5fA0W-_^Q"&^lDi:aWef?+d2p>aC1 P*76q!4M&T3T-/A$njY]p"KSCla\=(UAaWKAi@>iViK+" `]F-EJk2b&_:6OZo9rJ^!tWW/OFNC<Y?I1bK5o1N1QX8]iAM>N<3lF ES=MTpc<kpe1G32)[*p`'At?J> S-AnSDq0'Qf2,.)r5q!MQd03c8g=VCR:)CEe[2HVNg*7p'+Bp3^i#3HjDQ(7i#!!XSAmt 4P-K;,!k9iJ ijHq4k]LZ %KNOA+kAN/^X1fJ"2I,0#<1mlMX59[XUg7ZEm,$GRW\L%LW>Go/qCES.A-0D/fBHd3R("7&n5[Vi;&q)4Rt)js+YEJg^0 &\V9A"KD&8r6t-@=$>! (2aNc:5+I02R3qS9Y n/FBP%$;&T8Tc]_X6p7(;*D)m5<#b Noia*7V>Wha)9/Z2i VW;S"8h=LsYpW;%_.iM3=#g`L][H1rEKIPHVV->?):`8!*Kr2<f)Js4rEP9p>Tl?hq!LQ;\4=rAfL*Aa"RgH1_lR&S?F5HAjP&T0PIg4XLAYRAh [a1Q+lkSA [("*1BWR+$W+i&G9q1][oPdi\' V_1[kqL0K3ID 3h.MCX@V<8Q3PDP4K@=]ob7A)cI*6YOkn\"R=o2@2rXaZ=h&&8SLr'2?8ht `2Ygj?Td,lsoe`b9c8hMpQX&,:o=A``PAX_W;(+4)UmgC.k%k1`?HfBg(.l4%r2 b;s)4q=/kU07;*Z!qJ/3_n$j9"=@p<([2LfI7M`##'[*meTIHG%AZCXWg\6SUo]>aLFk'&#RA5n:oZ,2raU7dIE)l/eo6S<6^EL+tZ*dQ^@m.nr6F`-;sX'@'hOcoT +D)Sgg(\5B/7%-ckN^1gB7<M-*YI([hqT]s^4L7+,6<q%`aZk[8M.DOX[XBA3q350ViQ4nAsbS8t;X>7WogW&+=4:f"d."r)paXl3>HBFX6XEGjLJ3*ChXJ<s&`2oCRXeDTQY[OLD8`t-H\f@\1t=cnB =0PkQb:FM4tc2tLJ!OBR#VU+#mS1GI:Kb2L%Q`"*Q55c5H8-VnAB9'>S)k.IXhHZXITitshjDD;mSU43qBRH!,MK$AD-&H 2A"H?q!dj^rZ9= \TYg;[G`SU/@>A`0n;(a@Z/2O>^1=5);qCFnM*3EnN-rSQC ;"+$BK: ?ZjaHJ,FCq>R@cBhXG6\Nf?Yt^99f!pI2e]S1*\p)78"LIY;AY+f5%hU`s:heEq;At/0?^2n\V&=pP5/n`KPVO9UFmNTgdZ[ZgVA`\ILfOfA/$\DXq>@QZ/1AC:73)shS_[o;&%iW<;^2M3=hU'@TOmK>A#)OW`#A:N^@bWOpi@[3st>adqdQF>5]CsdIlI;JrleEc;"dtUI.iPA6A:eTAs$G^oKcUJ?+ct4idA+(`C$H%M?G42c*h(3Fa\7j^#U9(`34N8R1b2qJ_dr6dhKdU62W2L%];]8MN@ipji.6s*fh[Ji@bJ3Agpt_cIBU89Tt('!t)B'J`3/,W?NaYSr92X9t.n=3A.djBQ3Sa0p:@8/oqFPYh(*P42s" 8@:1D\>nE*sn`/"^ATJS3W/?atV?Bo&P8@m1 HK;AS7+K,*FEm#<ciR%3'[*GYK o@\DojfNB4?*!/2P[!.<rahUR!U5MDX_ka'l_h$ cKWN"XN?c:Dr`)9'hE[2c6mD[*_OSGnj$65o$>4X9_oqJjXkHg=S^#8RWRp1`!j)k*PY. MmlA&1\r@*t$//AKr8F!R^.bqmse14(AF&Z:Q=o*LSj:>FpFn(erd;IsnaOKAmTMH)9G8G@YFp*(#nh95M.@?iX9,lK"]%r<HnW#qJN=[^I*9=b CC</N@eVcp_AB^+N'ATI[FW:73C<4\*>><p<^' T01#ekmY?7leqSFN_a? jA4B'I.VB_K:)P4#;<V]BT`6=ho)Xd]k<g"A?a!!&o3C3e=T1D-E9EeVTo9o7BPRB7?^_A9L!^Cj&h6f4gDqOE_g'$opkBmGp/Bs8g+]`(LG\#A<F1]=%\@e5"9]D4c3="g4e:eSi+8@O$g>b4#CR*A`cT9q%CUV[_(NYU7LJ%ciL(4P=DW\G]/7)=M31E=Q=._hI1+(Y#4e;EAK9!6qbZX7 9P9YY8q7a\#PeKlAWO5Z5A(1/@r<VL=>1?J@FA:X5[0+j9I9,#)>26ScaPBl_T8G$RAk4^b*K[F\k653<aALe7A<nT8T0 ^mZB9WlJaI))n!l??]`9SjfY/\Pti$+B50"hp#ZWBm5NW-j$bj2)02!^%7ZoFAZ.JZO$/%-2Yg>JaN1Snf^lBG1o=[$7<``l1jAI2TsIl-;#.16D%>E(C^t65)0Xm0(CkpN9F'Sg]VPQ`j/D3?$G+?L;)$[Sg$(^80m<].TF&C+h8%[-,ojf;GN8 qWYRg/CPL$qj7b?7h-D24*G1mC?c;"Bq trOD*aHJ+8:4M1'8AA,r2*fK!%&P)[.nQ'af=`W6<gE9T\?)l`+--aAJnQ_OSo1=dmnEZmdR)SD(+IshZn+`5e2"Ba7,Vgb/'#?qNL06;<&#BdQ]hS)MnrJ;XT::XPK!5"T&sc_@0X .h[1=.(;cf5*doeLi"=?Pk=Zmjq G"YZP&o4^MB("HBgZ?[k2l?WNBD5 :,,[[+o1#Y3koq(p9t0MIjV/dlL_-jJP6n;[/e*XWW$'SH@fo@j`(c^8R61arG&O%a<ZW'7]"hY":csZtB-IW2l[W)N53\_\ M DeXeR"9P`<>/0:h9!9W06U2&YW*=m/K2@ANJl&KPS"e:=S$)sYC< _8E*4`=d\]NMLW!R*=5H!@g4rV7F)AtX0!^U CFP4e-:b?0AOmp2+UQh[PYK2H;@\cmW*!QfTraE2BFWQ]\M1jBphT6>_?#8A]'A./9<kY=+Ip-?5l-&Y1Q./Ub@Bs+Ae.3s7:YTdSrKF]^li@*( ZN"%,FL93BPrOG.A&7I_Hk0*C2U *#WP3V"=ris;oN,*`o[iJ:"RrHIOQ:e$FQpcMqLF'Yc@ERqN&PB;No"YjE+JlADehI^-"5s+T\XNho-S<,0+7SF)g$!FkC@r3$M3 _sB_+'^'!JcQ6-qL"U<3=1o2hL,% :jV,:EJ_1Dft$6'^7m[A:alJ.bFa)MmNkZ^T-SH.4)Rk[cHY(7T2@I8Y[4XDd [!ioGAh$<7?)%i::pZP/p<VE"ZpD.@M)DD,R"Z^raq- p5%UNiX$_D..(1,6e1oeAFI7#n-C*eSlgjrS)C40pMteohS`(l(?$<TdWpd($/Dqa*K!Z?s*;$8_.XkJe&n;8L>'.[%o8W_KcWtoF:*>W,6PKR`P=$N#*b*R.0.F*gIQhgV`)j3mcLZDpnLK_*&=@)>B'.9sP4DQV%dnb]>=.f+bMq)#kHHUJ^dC7"RiAL@QDLj#r%A#QV)`5.<WMs7@PU5,<9Fspt[AO#1g kTcl+#^,ON`6;f;);<?a?g;rG.N_#eABHX1.G,"\Y`V1Z44DDWo^4gKGiWTAB;g]';)^E2t_rp29&-64<()@No1`q-#!VDe>6esha9J7*>-[C#:&N(>\tCV*aB[]$XQ3S@tE<$%^Njd>#n9>.K.0A\j@pEbP:FBAt9qap*"GM<X\_gV9.ElN>$]=Q7 7?kR7l6,)fXV;^^GfoFNL GVS.ni#P\@Me] <&>H5o4(B!g9<F\+7_YY"fW7'$\ebd_U.s-NeAi><a'LmjQiUj!@PB<Kp#bh1jPfhb;dKE@6m6b,T,9im,:$KL50lp=.g<>pUY5o%[o7dnYtg[PlctW`5`T.RprS0CD2m?*/a.?+sHk0BpAtr84RE``9iK"^$i=aMg_e79AMf_p1qGGjY,=@>E+E%5Ft PLFgKN$;bA)XYFNdg[1DPlck<NMsAb2! @0t=<B>ss5mfe"A>Sp@R`mL%KDnZ/=HU@ZA&a,N"cA?KOY*(W &UZ+f]Wd6R`;<p34mA>q)bgnJ(m>9D/c"!6(ki;AlB8UGY-?0m6l`l[q@J;.`RF!^^psAIHXr)CMPbDRNJ\dFA`oVG1l&\-?I5QpAQTF+RhF'!#=F\bOh.MsUKUKr;2:Arg'(Sn<Oc%2V=E0&LsO5$qc8dK"#`6a_>l$W078sP:kPhTiUGL[0Q<!sk8-8t(D&Bhs!nqg YL(hX!`Y03k:*R0'(f)A.,toa>!I$/!+)1i!@5+/hs9@El2XkddQ&JoX4f]cB>Q9#EfY':^D.I&Mtl.cAR@75]Q\]PbSlsX"G/Z6$NUe.$Q)+gGpF:I2iJ@O1HHEgA,d=ZZ:-jLe0U4QjDtN:pK.CV:d&_^:U(,EGZPF5rA73&L8V\ t E! Vr6\J;*\[NNE8QqA\(m1dQ[6VHT.\?PWq.O:l>"WAm+H^AdIs a_H\2FS*tLBZj=*oi7+Jf!T##@ <Kq5IqVPK9=WTOfIXX\Mm LmXd/f[`A&Y8gK)[;\$=eoWIBh<Z5e`Uq&^K2(%p.T JD`TIj:`nf*BsJIm\Zo`Y#c$3YE-PAQ24K&DE9t3a2rA1-JNo)6pL".L4apa<,Y@cO?f4d@d;Hilg[9-"kV4DKc45Z2'_?OnC5ZD$<`:A2+$%<KqP0W=)!6m(#1Bf\*r h'ZC:&"NGQ(`84k9(<U:3H[6t%@?OfjrtaR\+fJXFsGU&[tB23C5 \9h 4eF6b_p`8VsUQf1J.4M@DoQ\=hpcH>'gR\Rgh(GL0^)a\?aZ*53&&t!Z9_h)CCT"]^?XB+>/ZD>e,==9_YQOYZ@=4C%J)n5"t<7mA+<e55U)s9!.>s;l\?K%e@pCjq)Y5(QCt>[&L4m3kb&5/7'Kmq^pWUME.pNKcB Rn#b5Ti='Fr;c64M!@Hb:Y/O(=0T]K?8JnVf %(:H<59Vl&6o#ijl&r9SQl(#?Srmt'#?co"JSWBT"7)PanS%Z_=4aSf.:1-Oq>266R>OclW]*4h9_A,j/^V PDEN2e7cnnNn6Wb6qb4E-RXK/DC_nkW5roNrb0k/T_mjK:8)P@[ i^-:L]_?JE.S^im:89(g2?a8F\->fZ\\YqY$79i>p8l."H/EmBP=QL9JX[jB1N@,c,bg0f#=/nPLaQA0'a,oX)<B"@$GCO3CWHdAhP4PKJ$sH+Z3(`7t4b))T$WMgJGSp%. +?Y0[icHQ=e\GKmE5"pQ$>C0Q1TQLSYs/$;aGm 7mC&<o!2/ph`YH;ek;#pT7J+RO19@k7D0Xk4K4.sVX_aA3FZfX3(9Pko:q%PY.H:8@^G&pL__G<O+_o(Ua(n>5^![#d?bcRl-kQq+3WtiAr"EMiTTUB@Te@YkR`1W(TfAf8a?dP+aBj:A7C-eKSFcY?KOrl$U==9e:i"gA(?XBcK`Mo,)igG6btA:%C$6shNsn7=[`83AOth^RM*W%*oZ(I)WKae@:K-"Jno\#OaH!"gYq*Z^d@97OX4'%AN+lQWgEd*K,\=L,iV]!AY'o!ba+PXQiaViLAW P@Q$n!V9n;].sM$^o<.[mlHAcK?b*=XcROiN<Ch#k?6CicD4M+5'HA"JL'j1\s(gdS<*[^`:i?`4lPF?CqVqf,qm1MJj;o.V,X]50r(t-JTQ=Vht7!I_To!Y4#4Po'K'g#\;*%qRM& SAS/0"^]A]ZQ:X-VZk][D(N`A^7caVN+:X?%l?t,g>F]eVD9Yb*&iq&TWnlFgb e%1e1+-@ gN*Sb/1q;IZ%mDJM0r>Yo]i\ZA!%:8UF>@CDT-e&t[',Ag5#0GJhM''L'f7tli1A(rPBYUhe5U@\%!;3OdHa%qO4V>!B059/Z.c4-8GCm+=q0A]b;41rQ9W229`FprnZN1o!#.$^#eAp5R(*1K;/\i(I0<_ISZ>.?\^Wekbs]eZERn@5"3)OD=QBrN[krVmA]00HjR(j=.=3.#G&jDT%*%[0QUAh7RGV1=O>a"T/KV)b&B<%JOM?!dkEf-q^/d0Mq-Jnar7HsTWVeZ3j)ONakRK_FJN)[YTUQdsC/$^Elt/blPLHhiW81hWX?19KVeeB()c(piE0CY*HaZ ,dpSJoWHnrkW)BtO<pa?s;M9K`E+1]$-W.s7pCC(&AL Kp$dpX`/Y0@RZ5B[;1Cm"U%*D?.!__E<[s=$XbZhT2iVH@[a4JRDt@*XAh]eX<V,\NJ"hO1F@-! (BO:A<k7[F^_]2#B8J8%.r+Aa$^4AQ$#@O+Ig9gbX2Fc]=QT5)'8]5B2oR_:9]P*l+D?[V^!5h&3p3\]:5Ap#7LKtn<j0pmknLqK^H("h'\o( IIgNO'Y!i \nF@l<.\R2_Jia9p)89PC;McU4bKXm GCE3.BYl`Wt>Arr4pj?YM2555jKLI`2:&A^ad)s,#0K4mXTpU..-@*FDU@TX.N7>%(h:JBFtYkr!KEG>Gh5KstO#)H7Da@7j!erQ`_6qs3 $8T6D1gP!5H5\`nP-_TCk8CKoDJLNX5-jbnhU`g5:gTf>g#"\QUk=VoSJ4d@NMV)ZYmbP &"rDGK Q7roi.+^XkhrP\VX!m(:-,lEY*bd3B#1$*UY&ans$GBc*:E3=&mZM419#E/mettA@+'=grDQJLY^]GP42R;c?JZ5;;LCnD0a)nRYoftWdk4_c(5#A?M;*D.!O[lT\Mn(2A.$F-H&+P/rg&TXCZILAc9YjBXA'28IZ'!!F6A__mBA?D2CX1:H?hQ^54O\Ba;=F=?rYPk3)4.^c^=OV]b3??]lU%$!*g`YkAa!GRG+UQtS8=)A!Y2='d:;#Fp8B-X3sl'qg+iW.EDU5n3[1"]1\<^4W"oJiE@Ma*CdFJL9`K%-4 'lV:5'G`mj)[]bgA3W)e"3ls`aP%05SDcXSM]d$;-mOc/?H)NV/#j-bl0YG2K?_c(N\5AtW^7mP?b)3;!!$P8\2BRsML.(/,.9t+?d>2(BZCk4AnR?AG*Qfd=c9GAEfXIp9(a3T8Wbg&+A_MN]'p$EeTXB0_4LUB5YiXOsMigM*SY2?Z9+&=gHlk\i7*-M'TP!e,!n<o>b]0i21r6EY@/c,*np&P`( Y4<s^=Dgng' J"02:X%.ATst43Z;mN#hL6@**0Ytt>ntisD 'R4DV.h7e'=gchIDed:U<?P_d]h^J!(9JE\/NNZAoKFA1'''pWd]Z!HFt=+H\?U3-I1!#\;rHr+>?bR9=NO,s\3mm<lSm*]cA_`Tj"3964YZHtA :fYs:Df7f6OA>[#O+:8+6?<J6MVY3eog0oTM8!Aroi&1I//0]^EQk-kpob;S%kt11h,"s04 4fna\a]N)^5+Jt$0j*>hRRS@*VAL,UH\Y`"Da<J4R6""j5HnNI$0-iTl-3+Abj?DG6QMqq7iig)U^+$MN6$+dsm+^V4q9A3Z8!3i'ej%i0AS78EG2%rH=T5Y*aj@B=DnAgmMcU]W7b9-JY!+lVXTmPo(FhdrnS>ZcgTFqX<"UYE7F^DrG?A 2l3dZ<46f9*"WB"Cd]$&VAo!JK0=YnoF0QN*ATZ\$16RY(qg]2F5&\,(29'(H'8q!)V_'pI1l(R'm444.QZC,@;7AJmP.< QnYbCkEC]$2,%OIM)'snFB^4T%&X8RMOS+8Z\?J/'8/N\2Gb/<20A1\V0IN$(O.MDh]MhK+,NAN'$KKfUXb(L/A3EWKOk$Af7;ms"Jrs%)H#VL>#^90!4<KS35;e:oI%GRaF6""Q:l(Ch;!7I&-[_m[\Qp/U3_)a8s//PYdoX[##6TTXFL%HIY(T(;d\N#d8I55X"6k55Bmf1RcRB!(BB>2jF?(+btekZPD-_>RH/q[hY%eNS;MAMkAM3[E<2M*6C)HQ>3+I(I^hkgE*;Ai-e7-U53bDR.E?0#f2f4(gm"m%B[2J!3MPZ\DXn33RoBN=>op\XBU(.:g^)g@'<>Qc#9e?Z[55L]jnW_^Z5U/:+@/`c9s\K`)6OZ[go(agP,i+Vpbid'A:N5]Q8q%V@!+/*V%Utd_R?MU1e+;@:*GA/\DQjcO8H])p:4A^,i[:\<-1tj0VXI$->% /5m(OC&";77"BmI[^.8C%_;)AS6+m,;j^hKG0`Nenf!@%oT [Gnf.n'Q1WQ,SMVp\'rI-M!tHce><V6:k5-N`h2qAGfK%a,G#l^D/l q&@h0edE6.P C 0`3btXKsBKFg4:C!!lUiL"5D[+NStAEB;A@EW-_sjc4hb5GBCEQ3T7U!OE7dN31C]B_ &Jh@gN+^6hk\GDaJO0A>(+B67J`NiFJi7SP1>j>$)&T#)tF_b;p[ecN,Y?RN!$F!/_>;(>:;GVT\dJU#nO-qXhI],t$V1aD[/]-[2B1%l0i\E$fDCmGK?hnG^p?K_H)\#UCZ)O$C_&JDX$F/_o6UJ%'qg%#r,`1jE)lDL^B;TnsO A'mk5pi/1Mjmc!AET;Cot?F3[1J"-(i*X%eRGp$.nKfVJ=A?h)4B1W&b6=8P."oo,?VWWIo-<TdmdG2FEB>Y,DZ&DL7]laAWLW)$sI5\NQ5<.eJZ?5(h.L97rDJa4bb&AsH</gZ[5rZ\mWKlQ%R#6rcAbsfH1"Zf322_3l4(cT?q;dB;DrfsK\mtfJ12.^c!hlcFJZY7qY\S$OtHXpPIk<mY93^ %Q6*pEZKD@n*Z;:G<:sQN6,6[-tAegs4'`S>^!Q%=5iSD?h@%)<Te#Ad-R%\^Ahe\oF@*'f0 n-\5R:,lm/n5_]iji%d$;!]W06#\Bo@D:o LPPEM@d&JW\n**q&Y:R&E3b0>Aep ]PP*9f"q8-]Y$hA+/bfbe5b-p!"H(6C^P&k&sipE\-"cb],a[B.kh^ ,"A=/]B[)6L7'9B#LjOR ST/]7ID`Y6/n]D^j+[A@V.&UXVnS7.J0Pt)<-[tZqCi#sC2PJ*68,ngP?: D3P<!*)9ta/$=.'q^dIRP.*ec*2/^Y<k /V5DVNTMm%a!WONr<\_2/bWr:V2+islr/&*'Zk HO/d(QsdPjF0l! !-Z ; lG%9Kd[^5*5$'hPI4W`X0tse*k;Sq75g.s]:e"5Z2#-%]rg;!kQKk"gQBnL*6:\eQ]YOr/Oi_Fmd`)OB(1r<J,P=3eH'4n=$h%(-Y*;A<M&3?n?b&&J>dC&JB3Db^e>=g[lEAA"1G5p1`7nr@sDgt8AP7:\dFYSgB\e##sM)kQW=tmI?A)qqFKfGn\F>5cIs 3qM0\fC]KJL?A$.((ij8>";_a2[=Npr[H",#s(=I!a&*)TY]bt8L&bhPq2TK7kGdQQml<[*i]jF9o<lpXm7"R.m=nd@^d_*;*32P `cR:l#kfVi_Ct1!r_cb15R>7$]gK=dd ;>jU%4:(^nqQc/c[>T]iS9sXK_UH+UqrL!lQdM&_S7gr/tbFA^P2"#f[kYh.^Z(U(al5m@TL#Et$`(LO57%Q c^t1&\4dR1F lqANA+o)'@/IetJrJb%b/WR-$8N$A=d38K3[is;Y.#7=Xt)cQA:lX&.&;cdq!si125Nr#GW'f!"@jX#oNts9+25Fa5[jt0VNpBVE2<Z62'.@de_`T,K\!$P*R8R3r&cm+*q(dVrL0/]j1p/r0)LdqN;A3'tX,EmZ*E4IZl8ci6\^Wf:=J5= rn^2Am]c*r%3E//1#Z2VCD`\97!?:@qoN.#.%.@c'D7la&ZK&nAeC+.Zg>7/@4IPk->VGdg$ZOI`c? TP)OFJ8`%nhE@=SflQsXQr!T(@5hPA<A<G@B?B7)S>F;mVb@m6<2LKDedE(o@r&F>#F?,,\Xb0c"]!A31L(/7fUf4N!Z,&O7n4YhpK['K>FVE1R+oT'4)YR^,=FMNCUIa_hS=8''%VofLdgT,Ik*DggSD7*X0:C!'`PY]qfrU+76Xl"P?sZKmLAgn*LrcV^#mF=1'LN<6+[.@qTT0;0#N"FIV,F<_s=^`nF$tm"1h.-Q4Ri0*OI2,iJg05>*X"!i#_ctf)lV"?kn=1*0(p_]SU[%U4J2q,LAA,b-h q;BFRs6)kBgp'L/4EAU/kf2+KP_o";?t =44MWelLiom7@UfkO:N"k\Z2,=AhrY$s]'7&A&A;_I8Xc)dMP`-*Db9&U8>YeL<4#-d\eFCM3;YM1;A)8\LL9q1G[fCd*(M<R&ZTNICKqSkEfD_A \43Mn7e$1$oC&))W?)Y'W-0ebjkDZX;\5r+^b628MBJ1a+@brWkWEAagc8QihI#OP*Ai$KHhkpBW7.-(l:@H9,K$h=/E:2CsHP$8he3N7pql-?cPsHfmAXSROL`-GN'Ihe/I&ia'RhVNARA9a V`Lb!bXJWCn XQFG?]AN-?Q4!?sZZ``I%T<P l`&k#+^@3P"[ j/<#11rEF")YP<E-rPNIZ-Z;8 L!)X0kDa?-faOs0P"5D-\Y?1c6(;nUfh?CC)K 72J6E#Y^qmc)-)mmsA/28[9&4%-Jo>USZk"/LTs42#&YaFl1BFQ*-/)a>>@2X-(;ndjcTGT d`o(p8ESY&Edi;q9?#:qG'"AbAW2$aK/;.UjRU0-@Ih:[$n!c2I?n'^IFArki5)Dc2,'XQTO+5r5L(^N^PP $OQ',ET!pp5dLO-E1kJO9a2=g02OV?Z9DV@a+fASkLjo)aF"JNjgGZ3p^8g5^N:58?,)JK#Zn&4-eGrHXU2Z9OPj]p5$+/Z$-Q3=[Hib%jL6\6L3^G(sAZ;/;$!9MIe!sVY*c-)c9hX ^B8!`V0=CY5XW>FmA>3X+M2KiWJl#nRL/]<<=WG3Y=t;_j2hS?_12 X7O6lAq.%n)&@bbm-%g,e->2ipK49HW VD%@c6'SE/81mAL6?\Z0ig9"l(%-&bA@NPapRAeBosJ*H;e<K7<'sYW't &kP8%Be'C#,qA%jdM8%eZJ^U\0eTAbi)t?kZBO6`+rr8Hmorl.:&Y&XLTK%cA *6(cX*IPD-`fNEef;HtGD'N#7FM78r%)KdI8!e*ls7%6'(Nm+\/^%08*KBj4t(OU)6bdlc`XK1h3UH`(%o;10I7]=K-T-YY=JDoD<%HFfInO1Pg+NqW0Li]o>SBq5eNfa7KI\_`FAe?f<*aRKKmm4Y8\mY.E?a\AnRK-'nCM6R4_rZ&7@U".:pJcl[+SNVAp0QVkA.c_<3!+/-KpW#1#gPoTm$-AVaQbMm)+` #cY^(s1(\d3-pG[bQTS#X2e>jSN*6$6& :ZR87O>&7=1C,7q9_`l-f]fln ^b`^CQ^QI5%nAH8=j'Z5MW&BMi(Osr$*22[[js_:%J9Y7FH9^/$>%%L(e:gQR:f0;s24gOi&J%5[[39bQ&f/%CO",Y'QZ>>&g7=ag=@q&9Q*Dfp:7-"6hJ<"7dXNpIT1d;]"s8SV6l?9Ra7b=heU^<4Ackg^FQAVhiU;YdUIB&V_m2#B$/c.`Cf*AK[!*0Q@fBJ#X)cZpt$=pY:_&bJN<mo[hZpDtn>Xf@&01[g+j_Y<FH@@m/[oiHc:5gpsl;3b3T)Q(R^"tJ3>1bBqBk6tDRZX/\\lmQ&n0E:"@BrsAD#`8MX5d-;EU:ODs.Mkbf m:\"08hIRg^6C=kItD;WM$8[PMNbMJ)K'3#sbH6s>QSlh5o1Z367dNDXCRM4I)N>)SFn!:'E^GN0A@6-6,sETk?Ak8=rA$L_@39h]X%-5JAf,3eeCXHWgo^3VQCD mVqd!Hl\O$15c8dQfHVSnDCSr'0nDAS:Y/Em?DMWqc.hQ2Y*;WAK&CH7F'gWTSho?DTQOj2_!#LEBP=NA,><AaK_&KX;or*Qqc_A9t#E`p]$V^8\d'bOOG,p-S^9 Gn/iP<PLop_"\s&#fVQKZB(Y&X07"o'p7]sD)e/^gQ0JoIh^9)$%Ae04QMp*5#A+kg!e,l1`-2^NS[oJ8Q`(3,j1]81/!Q>KX5&>o;_PTQRO>\Y@0gCnerAWa!6D^+KF+YL.Z'b\-"6(F?g\OE;Fs0kDr"1qVA_PHSWXO&;Y+:2mhcGaHsS/G_Z:!'Ch<e_sN:0E($>Z7I^Z<+:?0.^-@IS@1@? ]: !"$s7!SE?(KJa*CJMmdD,1rRKD5O.6t:j6IddI-! UfW#H33O'YM]hLQY#JT;=5WH@V!nO@BSd-nSJ:8&k"0'S$Qt[-K3,m! RX'daCqMS-dfPHCBe\fEKRoF%ICJQ`NcG'M/SIfQns,7=>U[_4iF(LO(UgQt4h844%[s<n!gW<K?NPNA2DJT-6l@m_RX[HPt9.Nn,[rF/56mq"Xc`\&FQW:f[3_hC1!GGdd3'BZPt(st*/q"Uc9.ID(f9reXQlk XAA6#*)XTjWo>2_aP!mj4\1G"6fA:3./>Y!:&bP/+NL8:4c6+_-F +J_-[E[sV_J^Na&RTj._ 6at+M)2&DF98d.e;]b@4%KA9;F";Ag-"t8>l(-(54VB$\=lFO4[5tqc-,QtinJ*5]D#i14`&C@oSP9n,ma]*SXn3`;)fF6GA(Q_fl"K#gd$T&_Akelq#%h7kO2qN*YPY*o_8'2gXSmE,Y7K?"$7(KF[.C5imgT%87;WI^Tnct1@N\C!+qIT&a!0U"[)).N>,K-rhQ%p`W'RM<.JY@RHepUbb;?-3(a'r\;"hk^d[7H<I&3VH2EcAm T@^N>b-95b(/M/f4"so2f--WAPQ7-C<+!?B0SrE$eb.)m/-`A8+-j44d6]U"\QQdq`^if0mrDqa`P b0B/8cni((k(oTd>Z[]d8k\Glfo25A)^[)Z1pE&^5dN4HG^($FB4BFg%TK1^Y(:,M+>4os9N=d[AJ)qZ!o[J9$F:6/G2f[o[3D?+N@O4:U29OLK,acrJ:B..A%N[o=n3%!U5jleoIPD8Dc)SoT! r^B'a4=+%lp2%(*r"]ATCh^+\[KM@7 h7*9-S(fc_eaUK\AA`U+9P;DQ1HPb@Wc$NX%gOgQ:g2dR>0,e$g;\Y%D.BT_jso>FpDAFI$9I?FUMS1?$iI5enW`ICBJSP^Jmm)pjnB3.%s?-M<KLW+P0/njN1btYdLrSZc-Rt)^\oU<_=)`LsprFmOPC;^8@1[F61!^is3asPVVA'Eni)OdJK'7dqL^`:;t7^cP9#ph\R0Tl+J)=AMPBlFH)J,:&DR)OqXUt^+LZJA@(=0>H[t$612MJ_B'"R X\$aV".J!sEp`q<'>[nbZAbbm$Fl49A?LS%Fd%g;[ggO;FQ-i0B+(CS/-?g*Jm%1PH)gOR?4Q\IogY-JXn8S^Qf0AW<QC#]!sL1W[%rV.-,7s3BS#@4EF%<Z7\ao\Fa7Ib!//Pt'RPAM"^qK*8)RZm/NMaXWg=Z[(2Aaj^OM$MN!&$RIQnZ+g0s>Zt=HjmS[)Y'CjWrSUA%1&4>o`GA$gUU\LS[kB+,r`/cA-J.KWbjd4]X-*$g P\Al'q-d3q-AfbA@+_7k>AtIJlL$$M4qo21\SQFLo1_V[B;tT>!$^feIPTK)/)V>EYiEJOi`_) ?<BJdB<E`<nr=RhcJcqX`gJ#Yin,d?K.2 A@oo&Y[CAmr1j/1ij(2Ohl[p=GM:_1&:_9'RKMYPB60>c7Bk1)XJX#PtR#eAP&T-j2i6.=4tsZm\Ht9XAI+;M@Zj>lh6aA*P^9Ymg(-nB==-!A!JrP@Ujn,c[r*(jRfkdp?C`Ka'\tCX"c-]eWnE2]?!>E.353qKs7+!n 6#@GFonM(-?c#7/U `%=RF:Mq*<"(TX%6m'N##4BN`FCU]KA'IAZIS6Yl^M@.Ac9lM&j+B^nBPM_F8&U9A>4A1\,?]Dm"HjZQoeBS+g@P*r(0$h-(o%_)tF-^\Zaq[G!a!2*+kZEg1FIUQoQ'Is@!O-q6,RDW&L*cfTJMr;Oj@K-m4'q.h.&*g>6UZ=(NAE6(&A`Zt6_.a"'B,/4g6Hfhln\_$VK<9b%sD6DS1ik7n?VoNl2"AkNMRJ(srj,ggIqTJD7qinH'Dr"1T?,?%h<c-Uco<]qYh5_7APE6.!sA'D[Pcr+k]LepHG2bmBAdernTRGZiUJ^r([=(oV&OWNEHV^Z6icZ=$@b]<$9$iK<H 6U4<]f8HQ[9X-Q=o]LQtcYqe"h)`m&Oa*Ei1\nUCq-C:GABZiJMU.]5lP@ *5='qA>bS$j=<-khf7pSLbmIOs<af&TciBf.>&lf^:q)eJq-t<<Bp4MYX]R,p3l,/!L6f(Zp9$q/+Fn,<<qtY&;pLEPUnfo@kV6]lfE&lPW6+InXRm2bGg%Mo_Fb_#j.?mWW252os0'QAH9lBi'8c%lQ8\2sXi6gAH['BAoM6Jl+>clAMI"nj1["LM3$H.A[]_V;R5U&`:]b&6Y#jVf)[s2<3^EFT@'1k[m.sAA^O_^LFL5<i@I!Q<: 0afF/=fZ]gXKh1M'(5%DR%iJCa3faIJIN*dHkYY= Fpl1?Kh"<a558gPl90dr3q#brqD^Sl3bD>9`KL#`c@_.37hW^3D!7q-d+sH]H"PKBbEGaao'4X0VO*q_]DiJ#ETa`/.\VTG:6;/hY=Wa!&dS'jIhi#gQg53R29DWgDB2mM!@0YmiXSUjT D!&gnKpPXUESfKN#bk#]%`T&M!DV5H#\6\@D`s#Yflk3&2%qXLo/kH-T2+lB3B0d&IsS7IA^oG>>h%GSF V<Tl(c.j'6N,P*4^!dV)M/,GgO3Q(EU)KKAZ4YWF`Af<%3l#tcFXr*o*R0:;H.G*@s&D.3#ZRe1J7mFD[L1_J>]s/^>I\V7Whb<_U5;P;9SW;iK^'9MkJbf-b>'I^DY% 6/p1lqe$rmpi%@9QBQLOCh9Wa$ABDN&:17**U,7=]j`42D]FA(X='_`0=&J..5R6qj#'X=_SNl&n<0UYriB=h[1YL>bUtqiOrXhb)B t= cb@@148"gmJ<%kTK QA(<IM,'N[MkN&\``#J\(MJFkY+*hpVtsl_anG>T9]RnQM5*,[3K/00#\qa(\$r7<?GgZKV#$%Seam]F7HIVt6if-<f2DC8"5qiSVoLA]qZ<k@k37aQTED(EF?$5MFrVcnd7e bGbm%e*-./i!K78<[pe-RT=Z1/sDr^nNJlS5QWlI"B&dX'Fof;5?R2\pttL\cO> pID+>)5j.<J@DiQogea:[YWKp8$ehT/"\7/&GZ%&4TXHHXB'-bAHZ14tYFA@+gSEA$6;/Y/fS\6k87OCI"kiM*Pt2!1*B9SHM=KHiqXb4NpS:b USaOSpsJr8Ie,q&/00NR;XCOL**O]1D>mCf[oOPbk *Hq]Un-2Neb**1fRf$19k]UK#)%#/icFAV62!V2K=>\f3(@^SAhR6rO9i`c?MtkINO)W)6m9r(H2'PB gFG4,I[Yp0;d1!BqB[S;'L+& pVd.dlcQ<O]f*sH6qpk$5K;1cA&t7+67]MoX4rOq2tA=J7\lCKa]nH*hPS@a8H+SgosRb4t?=m 9A_bMP9.Z)>*bXk:70KQ;WC< <O4 0[T,\M0h3dL;rW*\m-A%C,B=p:F/QK'WOG47'$)1C*`/I.tc7*``C7q#;%Tf+P&?gn jN,t22cViK-s22LlGpZsFE.Sa;f\QVM!`piM`[X/BOn;b]@p1I3\*D<B#Fof/F:/4Jp5X`4!Ab`/ ra4j:RFrQjYq`!8AA!a;<G*is+]e:%)$;VJ<D')71 oSa<^&Xq[p"LB5[#]ESNE-El g9qtTB<n,\pCoOFWD3=>EFEEB.<f[50b;?X"Octl/m.=`A`Ac0o640&tI2VDri;p0^6los-<A4d`U(P1?*026IfW;UQ$^'as e+AXDDn@Y+rYC5$pA3 !"UmTc/WC 445`Ifc CfO$0)Z8W'*+2qlG#6SXd+NIbZ`Yjn8dBjYX!6NT8<27Th\HSHD2A5A/.,RMNe^8 Vs@?3<bA;:m,HEq\284<J,m\tdg"(C=LB')WU_b!@Y0R_>A^piDC\,Im^#IfeW(68F8jA%+/Q>s/BgLP1DB$OV`lJ`REf[-Z?cGs;A?ec2WMM)E5QT;A10:]\WaUT)s%-iC%7nSb6>=Qf#!q7Fjj+#Gs X$k(m9qAm;M_4/:AsX$Q_V!L5@1`aisf--I,&;AC[7`2P4,RNPD45@N?C`k!ZR_YRgfWtIfA*6Vok#S+>E@>19/TQVImrkno550EkE"V)c9'Ak:=[$#_,JiSFUg'rJZMD3D'fQUc<fT&:"hgO5pc^ZHWXNqQB(\EDO+m[!YAUldAB_H<nF&==9^g6=k#&Em3+,W.[o!T/<YIC4,LA;3AY$S1T4('W#o'bOi#aE]V9ZH$,T-qp`AFST\\8a?tk$20J<4N:SA*9HneA5r%VY" $E7K$qt-ng>ZsQ+*q/MbR]JtbAA;O?Qf.X,4.#q(WnbNEd7K_@]eeqZ MCJIP0Qjl<5XA#+c(53G+)42KD1'>-#71FPlOpT:)L=gpA>nio"mCS/C>c^t@An]C_<n#p>m?Kg$/\&fJ3U>TtJCaDf&!+O"S(\&i!0'Og;Tm1Z7t@"jbk[D[oI1qsV4"i@3Rcq&doS$0o-1+U*T:MB!>$E8qA:,s4*UFg]8P*P17W2"*NZWk6$'s2@ `bOp,s1C5>h0fC!gX`X@Q>># BH'>bB$BF%'kd/j/8KKIm7W_`R4Xa49b7+Fqb4O.qc)A`iVW&6%S!,6IE K4o@(lpLEUX96o=SU#cE:J1HKn5VFb3T-kJh!!eI.b-Mfke/EhEm7T0U7h+q7K`Q*]D0X6o$H Y8:Zi`Wsi*VFDtgRdiPY,A<:_M_`^h,YZNG%YhF:_I7*LF3`R.<-.0(o?; F2,A>sW*Ci][t3-=hpVaAQY?Vc`R@$2cY;'8+[,kc"r;fiQI(6[_GF@TU!Qi4NI*?=0/s$VR<_YZIdI.=9@]gakFqn4@on=`"Z"`/G!59#%^lhAi&:c-"Y1oN:dk;isr'Y7FC0`hEAoh6,2` Q-K*``XNoAc(gpA!A=[nB- r/\R;P`(=7j:UB/(W\F!L8+]h/#]*;tW<dP/ai#piqZ0sXqT_(LOb*8.=QQcln\CWLL&)aA)fGi=Q^DN$B 'Z/_^r$O$kW&dU39I"'[E`)$-X$\9 CI04eEc*'n(Pf>C&*A/Z0Y,Vgksst7)T^Rfi9=38]od>kZ\$]h*9cUU,DMlqhdQJ"?h^/;<Cj&&R0252VkXp(EZ!bWA=nn4a<\POCOC3TO"a-&O"a8Ve(ojXa!k#C6H-"-p#q9Hp-A'421cNd?;Oo\tf(j^fqkBQHM3fdQ']2l,Wa?i;:(<k,TL9^UV-Md3onB` O5?AM8Ed*'+J@T'?`'[>m:@:%ho@6ZU3'gmrAhEq^D2;"=8[O(h>Zm^,jO18*&>tSt4UreJ, +Fk<,;A1Jld[J(W2D"41o[jBL-P_Sg+RI)S6jX1.<>B rd.TsO%nj)X6l<bY>3Qd8@W.`WN6F^j+tJg]pdf4=?q@,eZg0&*-ALgS"qb*St>4bhsJcZWA2!A2X"Qb`'Sr@-MVjYLo."C@K*VC<!",q1ejO)A$'f$)<>FI 7kT1*A_HBA^M1i\j@.^b`NQU\o/c?'Cs6%hCQcD08#J.2$B;aQm <i f@.-%0S=al"^:h*7s="O)\W>nism8,ZKpA<W)YAEV`fS$Zic"4LZ0jAeYti/M1\\F55F"hgO_(1VTt5;\*.kfMF%^:QRBclt%EU$6SWi85Y?5m=;iL4f&("R]XZ[ bD!!n;21s&(='S)8(pOCqpi 'e?4Mb2o2BF8A<F14[a<A'$?m54Q5U'GaG9U; _mXA<,!OXR7SR#2J edc9 8H79p7,A?*qE\f_N*L'0MA-O/C4MEEXbDKZ>gh%.6-UU;le#=CURN+:R,$5oPeg7<.1(okE@\UHV0`\e @4Lto7<1I-jC=PU*/0rX*jjAO>U=7q*/-4\lWG>#KjftF@`/SB_cJ1h9L"as=]ZQ'0N&<Le1fAO[3qfr>0Kf`>Okq:oXe*]j'hn;[[dsd*q`5kH8_TkB_4-ESEqgMU7d02[s#OebDd8tBH+jo*<ZMWi6*K>MQ s)F$.-UKfl"9+f@4'bd<im8Sj-opD3J&o)hH(SQ-*:U?Jp!<^HnJXplhGJ)c%?Q$.ktb[-V4r8]I9b ^6BW0abHAhc-W9,SR17EE>0XsbR^=`NJ*#`.;^E,ftp;/6#AA1(VM\E9m>*4tY pe9V\+Odq+V4VZtYmNShEfd9s<a[$C`3tN%HWU?,p<CPL_@WU#Tnl/nd^ DaR"cW`HAHPW" 0#][5A)`<X-OT]Gp`2AsiC14S3pd(bsPRN&2<bG?/cSCd_o96R9\KG\/3"[,d6_G1Y9aTj",Q0da'mlFm=Q)\h6$aA?Q C<d-^&(>'LTC\)%4Kq"\2p`O,;(n5TVe.JjAtWtt%VBs^<`ZV(m@9W:hSJT#%IA,j5O+pA7Nac7B  ]b+__q9>JnP3Kd4,?'R$;$a!;PEoDHOL\GO3R\Z%*^0-7g_cpbSYgI=U%&?Z2JN*"c8+/g4n,MUeG.ACAd41bI%"%1=A->InkNKHVX'AU%LP^@0n<t`ijbI7&#@H<S.1Zk/*!5"@ rXh:#M<[sYS'NnPWWT<": q?t` GMBK^.+j7mdd9?snet0Lhc-C0lZ>4J=Z+:RtgP<ZPO[_9rJD;o>;#C4#r5!]4<XH`-.K:2=;ZQ1P?+&#Ap2Xii9DO3#$X /pQ^tTS*\a'U"CkRkAfo:NI*"Fa'$a/X!ZR1U]SUBGhN3m=kctBoaT&m6^)dB>kXAh/rtSRk/tah0h#qq6*UTRW)`?9;_&agZ@<J"L(d9&%$&W:rIWCD;q&OH7<8@nC9:@:E[7U/&#.SKi/)1Hp#1CV$[!O:(Gceg60Y!a);BjF:gbLWW3,65%1qEJ Hj;+0)$rN q'#g# UOcf@p,^WAsoi&Y4o(ID6&l5%sAjAq-+,"`JUV/B5HY070!'F3kNWTSb[A9!gNFG9%3-\^*Ieh#e9'_2]DnEg3<:&TeN#WSF'0,llsE+^C,,1'6\LCg/F/68aJrSHjY[BI1'&/`Z08'0YJP9&<=m,jYFBl N'JJ+=t>UYMrtFFj53\c.Ane6QQY,%FtlTt[: _>\P`WVoMnO]E"ne- BL>nM?r_L(.7P,$l <'oV0+_+h.-Yl5hLP_tRUMYJ]#`/5@aW[0;rZ(\DmXN.XR@N&jW8_RL",/`s"4V-[l.VF&DW1%c.<-5p:fY$"bCl3CNM[-9Ji^tngOUdo9WODbYcd)3@r3#hHR'3/K&/DLA\LNkD dM:XDU`=)S3tKgZeTSt^?@Ye&1];%b;NI4qde#_^Q+mSk"caS%p.NAIU/6/Rqq9J/?X_e/^W6"Osj&3QAcf,A)+s$NA7=h2I*O PT7!jOd/(5RU[j/[J+P`2XM2JK+q_f$bGlJVM*B9C@IWNoD-!>Vf$ClFqj;J5\@PX i8T<J>!PLA@M69mfY+<X*5AH"`:nWr/R 4[Ei<d(?-5a:(o#T_E3UAI/P7+LsB;&3Dd \:h?pJ.J.Y2EmW+%D76]`[>$Hj&GV36ko?,P1XL#o#5N]+.>Z&k])W2JOC-,Fe,@o>@H+/];/0<!Y\V3DlZ>kkj+aTqAHmYBfDiW_:I!JApEq<`,oCX2DI3I<V1G?a"\pQ<8[WA>8ls4ZX/CmRi+_LMX4)`/b+Egj3W<&Yb)-,mq:[$).fYR\230Q6N9J7pJs#g"EQ\:O-#lp)@e`NpB[LHo$_JbNJpt&-5..ct@gm_6)]A8qRtA-P1b7-r3X, V<^OHNB!VLciffttgVP`1XLDJ!Us5H?daa?nspLARhrasnA:iF[PYI4g]5E]6X3EUe5-3AQsMm.*[J#*El(M:SIf])\A@hJ6?U &*Q+sJmVC sE[ n5!WVkb!?+n"Ab00Z8gnQ?i=FC2B%gg5qi;k#Cg>8"2o*6YpO_5p7D4g/c6ESf&'Ao/TpH>WhrpA8U5tO-g#>t?SAgG/-h9<lAL54>gYZ9sAX\Gsc0m$lG^/%%H(gY+E#!.iN6BnR`Sh8;7.-ndY8j2jrnC92f6GmAq""UXsE8-(s+n_3rN&04pj]'"8#TV-W/etb3T;$q=%>Wf1S^CEZVr7q6HV21L`<pg-f\0`ifI`/fmVe<R-5.[iN=M7(o[d>6Bl!F!#'UcL 9A`Ltp$=bS7kn3*8cc<+3t6cr@^Rok=*17%(KJ; $0WRPg$7#h'--o22?aWnC29!Y<B2009oY_&"(2@l<D/<BCYQ[tY1Umh++L Q`97*!ZN.V!elE2n0a`[IEQn<[08/07/10CTIVE`&"U#Ih;t:YK Dk\&0BKkQS\=.Yah2nZU$1T/-RKXi`rcB86C5\E*L^Og!s'?s"aGp`#_r&d;>Pe:b$mhLU\XU0&mp4UM=Wqrs^htO1\<ej[8"<t7r\@'XhL5./X,>>aCI6X99s_9C_09XU>4?E<(Di:\Rr&n*^]DWsZAI[iXr1Nr?j;gfRdO654c*'/k-D-K'k^/)NTL5n!63.>(&`hrYB'/-2c4lkKq]G YijUHe@% <O]%H<'Wh\9,t'6BP1%&iciP*Q5^S%]rIiQ(=8^D*t2be2(14bZ G^c+I8%0n^,L+fb9\Y`8.t?GOT9F6BT_Rg68]I<mUkAAH P<F6;hcT-Bj,fi4. jkE#jik[n6@o38=37"3&==8;)">bSaa!<HO#4Ggp5QU_ho6&n1T/Ch8e0E$f*_Gkp0@n;e.;.$Zo_9\mJMK99D8BTjG:>gbLLK,NANVFKeKsmA^pb0qWgWt6K2iFSc&h..4+l)q.%)F$C!Jg6*ofZt$h'"\Y''*`SRa.ct)R$ P2JRs0'eos&9V5Gh"&eaT&?HG.ZUBDEH*gD&TZQKTY07"i]t1'rY8SCMZK5f`A5pF-n`b)U&J=p8?^>+&SG'sn#.X(=Aqm^6S)KD@8mqG/(5]^Z4LG[kML3$>>rUX7]Tr,kA.s`RNDea#oA)8Vc)F;NL:JSMt_`9FMlVLi[MLLAU;Bhg4qXW6SB-6S+]!pkG&/IZE4.J&p\=b/Z6EN9*!Sd Q,S t3mfRlZ:$Cs6d9f j;BU&&\?Uks_bSLr<Qg6XoeaXK?M(U-TeeB@oF<S*<lL$/&1TI>NK_ Y S]tnmL?\SgkPL CKVOdIkl40H<M,sS&B2c#ommg,\J!>VapSC& h8le+Ob"7 J@#(E>.`P`IO(gGW1$&)m,j8)]FGtht?s_B93RKA0!^?f4_G!tET9hS6Q0/33RC$l'-FfdHs)RAH17:IsPSD<PmlNIpQgcWUs0=6?;s+K@NAFd.XBkP2q5XJ%Xcairqr_qfpS.F=#\']lSo1pfm-U\it.)M*HGJ<./SlAiT87eU4R>3Y+L8\e-)W\d`qWrkkoidqt[A6PhNX?Hc,kh!,?,0i#TJAdmoaok['CQ[(*J`8=@FQjRT@N<Q:'-H;2QnVbZC@1"f7'd1[psWO4Amt+]ek!n$jA!cQBA##/-KsD!M@fEI&6?KSpT*pA_.?IJ0MqGQ4*0(_ZG?1Z64:e+F!kV\sZgA+_TAD8EF_T8psFsTYYmKtU)n[4I5Wr)XJXN1[$b]8J9h3[3RLCfLY78a;gq&Vn%: '\*oRpI<f/K*=W8FS\<t@*;^[IeI'U0U&@`qp-h<P4^MBLP.clB'5UpY?@9*Qlqqr!>C31hk""_>[IhkY3E/635,_J"A<c#'#a3f<l0bSK^-m/b1-8PQ2I%aB6hE!"]`sj%K+@^B2+K\O("Z<VV;bblt9p!pQoVgp0 bcc)MeJ9X>`H_8GP=<.%rl'dpY/(`9Cp&Q=>(t<$fm<6:/a!O ^Y,%1&0 ghC&!F0'A5dqn/LW?7ehD5?>^Q=)ZB]0&lUPjW3B^2S1D&%,c%m*f^ @NT>Be<9O0No`VlQOVYlRV+=.sA_&ll/5n,@@m+RDkB(0Oo-E6$VLZX5kAmnr.I<qS<ZmO8=&)*;jO>+?h"Yte6A'Ia"8,(=LJWQ_b-#UC%m1I)6AS6<gO[Aq]oZ)RgP.[63 >$rJ1G$>Y(C;;A77A!C/B2X!Y1$L?Y;go.JT2WpG3O/al,H/Y4TP7\ 5Yf'A&^;(5d"kSGmmD/!7(C<la8B!L#:b!_UHm9,qcc9"DYAQ't=$jhcAQA3"[&tF3\rs;<"hiXI3I(#CMFk0&^73Y9E!aU:m*27;!4AS`,X`K9JgWoa?<V@r>N>1?a9Tq/!BmS%(+n8iJ#P[C.9\h6>1<T(&C!9)jT$8iFGC?fj;An]F\3K'Se$93Q!WqHt"O(D_ST>$O"5mZ?=L>UU7+r7A)g?g;)Dkcf`Acq+bUWt;aeqJe&YNT&U-^MUctE8=P@"M0Fs IZQiji)(!)3I%2:)k&Mef.MfPP2-b!\287:Q O43G%D^9T1e$/B6-_8JZ[ 'JKt&MM9+?&d Bb8IX-'tSaYlD8.=hl*Rck:+T!Y77.9I ib2EtT'^>A1YnIIF(A?QPAL-]4,jJb'g^f@[NRVO\bU)jTfRmX+m0+B+^O)+FDi*4IYq@m:#be*i"F^8N8^f^TJ!?W7$Ho"65r8@s12=X ZgBnWj^XhnL5i],M(#oFKs,YE"=Q<(2.s:0632=M_;Dbeb1Ka3K:I#NQZ)92HD1?O%e]Q"/0iWXY&Q8,7!HJnNs3tY6-($@L%^Hh8EHL(s)tlpa_t;+lW,]"sR;6(AX 08Jb3_VEBs'i%$k."rbc]Y(J"CnC[ES"Z?)`pQH&)P^T#V^J3Uf%:B^:1PbkacUf)p-T8Sc]AF2:j0W:b61-]N1khkK;^T-GD,1Lj`G\S93cH;?;df]meBX"@Q61BW?;N\>HJr@b6Uo`e/FJ+=>Gda\7lQF`2D<Y2glUisK]?(EO*NlsNSt5<N"#Vb''%%nE[@gL* (&/UY_&I=htAcTt28DZ7GL@%BBht?d:37!Y _5dG\_[-qTo6hXBM36q_`:5*DW -cG4j.FA,7`@Gp<Z&/tTo2 ?hNj>@pQ\rUg:_M)WfrR-*a(:?\:BnTFNmO3)_*741ZFb9?L\VNWbUQ\ iNOY<'=m[!K4<:N&933(!kAQO+0ZMh>:<^.!BL-^LXM:sPMhE >K<& P$$UKZ3-Er`ZUO'Oc010APmiXmC$YYLmqD<c:K6Y<WaIHH]c>OB:&JJGr0p_h`U^2!Zi$O$+qqr:X2QU7>g-j$rBtt$:=st_ST#WiWG]Bh(m#U?86]Ll=[#M)r'K>Y(Yd;*Z@OPnc0O6WBIAWqE%ChqLXP"4XRI6g>d%Oh2c3Sl@FcA+]9TN!1)5Z_4qNR!JW\(*OHor2E9Z Y<c]KoWZ@NAB7#(g1!X'?8Rn)J'cn'O&h8n:LA!qNh-URea-o;10&.k+sZ-Vb= B_;AN7@d#iE/O]`6I(Crn(`0U-nYED8MR?4]4CZhO5`>F#ZW3%GOHbk<N=rm<I`\6PN]ZL;4J/e_W<B2=%[OgQ3"fOPg\fPLq4jY. NfR).k@s;6*m0,(D$oW\O1Yd9m;'(.=4'W@-2 >er*[$1[)V/l'oNts%P3Yq0hbc_\G:!%42PVKSTE<e+a#P>Xk)ZL,`sRD1Z>Ht]ioAri/5?oa:%rO%/f\+lI(de*J(!W[Y:,fF+3`T2I12"[ceY`4V&'#Gtn\ H8MPfCF"l*d1/4iHnaFoJHR7tG9rPtsji[AL: pY?'VlW;I"31P ;SQsd6<_88#Vt?#0q-gZ?CY%]D]nan26_$07m[/5'm?0>)^EI@q>a N:g^9DMY!#g%)ZmtXr[T6"[]WH&g#Ds0tq9;WH9RAra!0qPA#0^AM#s_&OM0Arr/Ng0Ym*A"MY`+GmNeHKVI#Bk4& Q:oG-<J@=KXRgr0=A3A^P4BnL>oWQe9t+QN#GW57cYNorf(ETGA<MeVgorXY2`U6!=Qs/iU_fDe:N#IXs,)iA5ZB>(T4P(^CIF;\0s"r.T3QQ$Qn1.mk6a,$m"[6d@91Qrt%s!4.c7(nq[n'"*c0A^I!JoZ^BlUrAA;li[E-fC-F_chc>/IW,/VqFPOM*1+)(f=tmCBeJ`CBc1jAZ<'E"!pa%_Ig`80;/4H ;$'Z%9eJb[?W5NaPtG9T"tfC<=HRJhdRT2GRK5rE#9*>)5kJ8KD,8ap Ap="lA*c##gWa4A-c`if_oLc$L387$c)*TNVJ`'\L?Ok8lsV!A\?;?]46HkkRh,L>aV?"A2I$N60>K.06:4XZDh=6MGRheK(^]]EIID7ocQXN4B5HL4q;QS\>6qp,A3"G"GJCo"Te>5ihQ3`3r<(ctdP&!s)3ET*8&ib:1Ak08U0G`?7rg-AAN7&"lc,r?-6@%T-If4`m`/1Nq>m-Uq\hr\tl=hM:DH@YrM+n`(Qo$h9[[!6AsA7(JCm4J"-D0Lh^=$_OpM##ZRb5-&>iT-,l](anU0gdZA-=&-ag<7)glW=ftg_kRNQ043b%AI=r\!Ab6T&I!QCGQiX+[ADl:?%J,AOm#HF5Y6>/6Ls(U?lmlXW\Di?C6[a-[%$.Gl$&]9#d:#)rk`6Q`HEQ/ZR!dQr_K?;7/]>l*VAf;6-2O"#mFDfes+.%=CPbXX"0s.=C]Zhq%-r$<rMH6F>GDC1]fO('PM*K>qB.H?9h8T0pZ.l<9EPlClV&_C:lPmZ*P+Q0\;c]4WdZ%==5Lm/BXMVTH_-d`::Ol*7q1c]A*NNWKM=-/>O@H$a1c@r.=0@;M*FRARei!@a:#O9GAAO%Kds&>ddJLcVT?IT$-AKATC8^MBRmm(GW\SX/WOIPH?1imPf(^!U&2A=(nXd&^(]XQ"AB. =KtFE$A,-8/Rkj^7>cYE,f?Je-AF"l,CA,jS>l`Z?&00JV$_X6262,/n*m+enS@*k1IUG-1f'C9QR2lG,\NcdHf^*N$JZB_#m"4`<i\0oJC;?;>Sl cpW/6,)5nI;j48=jiE%4X_PFnH:EK"QRW?HZt-L6C#?V6ng iia$VRY>/X,1)C6*aU-mO;Yp"`Kb\oI>?9.<A@?nLG!Y'^<.f.(ZfbV/^jeH8bWaF3;pO@'8[+?8qg6)%]q) ^]>0_E3bM8F)%3T<HS91m(0EYPC<(JE__6O_.;QNY=-+K<>:=T  98'L^C2M,'t],;*2d=(AJ?AA7LL>)+cp^F+5)^?Z \@b.#E=m%WTs!3?5A+Il_aA)*(1H>]nC( [o9'5b5%Bc!k.I-(?Ed/Gn8:sl-(Z\LA irQ+LAqelk@EJ!C`:":bpGCT-%Wism20#Nkm0lX@fM1*XR.Xeh4pHSHn=0HUL Vf1_r._85CGRJZhi=Kf=:<Na:JU N2P_aPt+D*3qZmD2kE^Vq:Q/E^LR?Qm#O!NO^W*lIApPRDTj59oH*lttP3rFKe$Bs3.U:b_#DS+E`Us<BZLX3=4q/cK:aL8 /0T&47eC3ge:Jl6n_N6$<@,Nk&`?bFIldGYXilP$C1MV4'EDA1[8oMpHq F:FD_ZPjX'>a7(_(=ARSeai-bX "*&9TZORq.62:6DcMOFA(=NN37F]q1Xd)W(^L<Hp!"DQAgg_XTqP/(0CoEDhR+@Wnc"@2Wtod;\/moOnlSqf`VCehK]cI4%5&=`MN558%B=0E.s&G>5mj<,CZP$KDAr_[0kb7b4K"i#>= "[46g0F/0pPWVpNXUHgOfiV@&b=r* %s2?([p*jG7&re>C\qtb^_Y.Y\KT7GS0@m<0E6766[?_(c)H7JSqT67AQd3&0lUp4.`jiQ'41[,CQe2LU*.,in47K(`d/$C#"qCDHs4?L)rb4,H!]Tn7Wj<;j(f`rI90'$HQL231/4fq3A"cCd]Ob-HH"9`t?89AhYoDV#<\4DWdo0;9PT+9ba;E&.5&(s,,TFOGO."Aq\gn3-r\5#a& FAVPE(-fOUcJ$;*JZmD\b1fZR:'2'dS;fkfEh7B-kqL;FDp#s+[T'tpAb+cMk\819^86`6@'@k'mm!Ci3J1%T; p1TgG1mlKRe:C>H@N&lpR>_2'RG-7')C  35)H0R\88.5lFP0EhdH_FRPRRA/U*7op6<mg5ADOq[;NoXZ]j#\7VkPZ&I4"Q:(DQ(8#fH"?h ]!q)FqVd'`5K?h'.B ^7QK aQL!YhTiNYWtJ)Xga#g)1b>c@HrKbo(_6InOgZOL(I"d12 .7';]bcB=PA1\tD^J7q oo$"`"=AW7o5M#PclL?%Y>9P+/+4I^[k<,08C\`o!=?MQdHI]SQm$SGZ%r7LWG<f%IJ2gM@\mi[sTCrBm8Q*:8s^a!E5";IVAWn@@rXErsrRo!n^@WNYAn8[%B7C/YkZgi)F&2Bm<gS>Z_]Nm[G1Qi9,Q`Y!bUF5o);(q5rdohKafk-/)pi-Z/i#E/1Fpn&3fXEAl2$gAo%!9@*RDtW/")#H&jF!o$4HZQd(k#bT5]1qaY55B5NX*qAkh;^JAdlUt]tG.%AK6)=G>T0Q[Ld+$M;-U5mE8jc7%!QUiNae55V"1LMVqO%C001oeA9\UGglJ2QP>,]j[F?3bV&_X?N>$ mZY<\Af06H.HP"t\*a8!Vck8PR2io0\9!?[!>#]lZh*i/l(2m3%ZkF513FWEET;5f@?OhF&t6AKbYOn>H2g,$[\F7Do9-]dI!#!!=3MO*])A2L`Ii5)hV]*\n6;L4IDPgo.Rtthd<>HN<$:7@K9:!=\/0t'$CPsc(lF?jXTm*gA_5+X[X)d@EOnQjd8f'+ho-P7 Bo&02Fo>BaU<5jFKWrmm*3=9:M)U6<?;M/4c>MtbAX9_;cq$8eWP+YZ-VsB7_ZNntt;!HY5o0%NUq"7Kq]D`r<!6"W7$Y2P>Pf"%!@7Bj?nK.t6L%(H(:r eJ@A&)sjLF"OI/f!h#rS%lPRV:i3fhld]%\*;C9PTAJs_+F+! Srnq]BHjI4h;6AA&,7&j];Bdl;]X]Z[;H+.IC.537HVN.ZM1WFfK^o4aZ4#f:.Cp!rK"n+Q8q_@+99&AEILR4EF1*kV#Zi17-M`+#B-%C(I\ 8D`9EkPjJ:t@\;LAc(P6#%em7NMI9HhmZ,]@[#lH.W%&ejsADRKVa<o02ALDh ?m8E4d!LI9@S=35s%3#IhhDr/_ciln*:U4I;li$!p TM3&'#opi3#Ksc^^A#EbppbXQO$Vs*QhpQo[KN**(m^bU!P'dTk5<ThQPp1F"t9mKcj`Wjqe]#%h=A+Q"&IbF6<l^^&[%$&;D-bq?,?p:DpA.L#Y`7fhUd:XC8RD>!B1o%!RXJa)%98 arX7!r3!f($ZgAp%d:$9;8%Xd$1.a&kZEKbqS1 *TPbtBYQ\fY!Ct\- bBAt'And8N/Z3elFBm*J/J5:qY)A,o@&`f,<DK31#cY! F"7E(Pq\r(C+MPC5.DAqjth%nsOZ]`$*SjXap#P*-WsT!T*X)\*j?%dokd>q\Pp.fCZf\E5JB>&\`2H\1TP4Jj*&IZF`7"h7MgNVV)(Jg[2HC_O)ipS8<P&7^Lm'23qqO2mKKOngHAd&Pq4B#bOU0ZkQs-2UhD.DqA?JhU#%J;Ck$[h>L[^'K!lp3<O1XR?,K$MENo)9V*_"^bl7sQ4A2Oahh gh$%s\Gtppge(EZq:=3OY6 MZ1oSGmTqSL?ARR%= 3*Xf3g>re'pN*E"$M!GG]_f-Zh!]jMotT(32."?4;=o*"&Kks9sBRc98c=gGCGoP_=EA0R&B4;qAQ>95+4L]mP>%,$(6=@G-GO'* F@l>I-q-RqFB>?8@7<4Hb;(R3Jo[Za_dIN$=I'W*r-/.Rb&.WK*lnL`iVrlYa(GNh62Gt#Z4L^L(o>pkCn"oNI6sF\%0U[tLrdpq,l&NWt4giAdE&08K:ar6nBh&kH+>,5O:EQij+M_[@g5tM%TFAo#^naVFUEX `cEs/Fo-D5i(WNQL:4`WQ/&#LR%%>t 8).'fUYtMl?QI/3KE")l:.7)J0)Rr4p$Ui/?rV_Ui%YfeV9i=lGNb-I$HmR>q3(kdPB`LZf"&*%+"X*O@>nim?@nj+Bdd\a@i7tne0:hfH7WIJ75M*)?FUtYk?GXY/I"GR]gl/th[Liff+Q=hc.U&p]r<7Yrl07:T=\:(A1pltB8%dS#//>7%e;K_""NbN($:BP-i.aC*T?AmY-NM"_oDFrY3-pkL!EkM=ZFes&KC\/+:b?iA-KHX"AESPrS(*A>F'X<D,=9ih1FUanAA2`4gp$<=.g?TYcF=H"sE(#7PkcSO0.m0I7*.,GcKI8k]>)+=s/`!pPje] \"(EF'Gc&QT]n`9CM8W?4kraj?*iYB,0[FTt"3#@X(.\VHE;20 m#_da\(c$]3@CS?*s<ld9Dj^AW"k0$htA"BDK`f,/B.Wp=1W)LaA'Ok<dHp>js)U-m L[n3V@[<%e3-gC!Z)+_f8i9p.'p3 #/940)^4&P1SB#.66iPVn:T7c+/rtgOA-CaV$%8jEc$ 23QX9j<9lC[Y_VJp'1?l"577%U>>(HO?qmi\^\HFeU:R$Ik:^*C<m;Y 5AYX&!W(VrYMUnP876)sQjiNnbr3''%QkEE=?$#-&0QUXANki8723SiDB\0 %!\%6pHLamb3&eMWh^,I;,nd9MVKT``F=2R^09a0d.GNo)jj9ge)A0)k!,3gt8tKb4d(Ef_^H]%] H=U]9N)QEdsq24ncLar#O:R<Ea`Wj7@0s&q=5lD&@'nZS>@d?Jet.3@`=Ws::id[qSspkk6He;"kGSOpl__Dn@"!&9$IEUQtUM !i:X'G\LDpeEs:h1g4PJ]GmO@d:lkc^t3(D2WFM/l_9L5Z4#,/` F^&1:bXk9C_0jM!bdcd.j.1?s8O9i!Wg_P8=W13AMS+"MEf9j-'Q)^,o$hnsl@)d#e>l&+Qjh%hO=X_ZrARVQlT3N4Y![N`7,h_VXkEnnP`nTt\!\7!R:QTEK+'fSo%)kD0:#ZWe=*FO3Sic]i`F[W1)aY9kRIaS`@1_H<`hA9.#+.W^`V)Yqq2Hn7f:.2;a PZJEKRJAjQUq<?=9HI5>DYU.`Rm4*LX$Z >r[!R2Y*.ROnXYk?+]JJ`H/K6(G+(l0n/)tHFN%$P,R5_S]B?(AZMH OPbCX$*)T6"YjcMQI^B+; %:@\&+A$KTVB `M+)<@TZ;7$jggJ@b]V*[.jp3;I)$" L**>X+KHgQ*N&PDG6C[Ccs"MN-gl;jPbg)fdR+^_Ds7'`UeMn1,@a9`A:SG]UO]rCqXtQ_C j>AaHtKV,$-cN@D[O`?-A,<qk5cW((T`-%C_?A87T>nU1#!1Zd!R7nb@ZG6+6P''^ZhCNet:lR";8&l=3=6m'p9lA7m=Ht&g,?H"A`ah=qK\O]Kn=<N"1np-TWPq 3C"6+IfQA?DHK1""R6GYiaf`Z*+E1bI:@H?s,GA G=d-T%p1e3$h(gsml<dFK:q(1\RCIc`WIj938[tL;nc49'Y6MW#a?^@__*%(2IDJ16IsoA\bBH2km$\;I7#l5.;4t/F7"sYAJ'0sq>US6cJBAt?5Ti)Q8!K.MeNKn`nAU_Dh)=Zo_,R:>sQ+]O+tX&b*Op5*N__mkJdO*-+#n%3pn7?E 0A/pS`V9:VCi+*40;nXU[WBG]t=O2aDBU9(fLUH`AK(TYD( 9JJ/[#Cbm19n'3H,b(Ob:rprqVFfQt; )b&@WZ(tgah#SAJo+W%?6gh6k+*20T;Dh,,XpS36`4"6DX-nB$7lNq&X;b N,f)T?9lbGVFFL$B%9ofD5\5o)CtthNA]CWLAn67h.VS\Qp[7++]s/iZc,ZBJoA1j,C,A#NIBr6&!H>d;F37(A59@btq5<V\04NCBgA*L<BVF]>./1?S;.F*94=?6@PCIln`M1AaBoge7C18K%JS0m8_D;ZQ?W*4l`1Qa^ [[[^SG U%ZMXP:.4>FpGV('i@fZ`bD8S3<Gr#eEC%j.tL=l<;\0e`p&`)Yc?l/YHRSgDoktZ[\-N^4k1h!-VtPkY%WCX.R-^^Bf"Rr\^rB4I[M_=f3Z\HS-=[LM7;! E2*2'N'D6H75D7M+KZq>4<Q';J(")%BkV-jk2c?RljcE$Z"!FlS/( b&k+e+o(3](Mj=jl#is4A&R*Wda-UVGdA;NpS/NCB=3Z_m-+fs2s1C17;qf*]k:*EYe-5)oAS=%"g*_\pXGSAb&doD0.f\SUjKO?13_1+9X[\=KbSM!0B0C <ch<&3,H(JIB!!g)!>5PtgN( m?%;gP7rG"-Y8,aqtBXne5"_7!*0i/hG&jNV7V5FEGY3TW=L$^O2flhW?7.T1["^Ef+fk=&h!JSi9J_+t226p>8K:`[l^[&%AOI)oI1AIE0<eEmL^M;pWhmi\dE<^$r(2Th<.BcP`a#mM2X!8oAi-(6\_(63<4AicTAVFJn6XMIQ]'m7UaPbb&/b]M#A`naAB':@^l3EasRJA6Nod>A@2mNr*MKAP)W$>l-,.s$614h&b:hW@eWaO+qS7/`)EZk=P)@UtjI)6G^4DiWRB[GpK)=:&YY @ElO5-P+%BV\8;_H=0QV*En\TG%_YM@@7,c@%[3TDLVNi33!2i3-p4UP.$i-653qrVn0&A0F(n<YXO-jKZjVWbZNRb(\U]Vt$C@?AfeCm#KP\lN:B,;8k'T@G/l@l"AiWQV5Zc"E%QTe$m,'LHMB7ht3Z[g27pa,_\(<XODta 7#f <gZL)LF"gf3='a!#$`h(ieX!AYW)A:9^KNJRAAB"1q(f0J2kER"A53,[G*8Ds*"k^`IU\FS^7^A"0Kl?9*V_LlF#Y<4NUJti6ZV_MKf?p7QB5SCdk4`j>)8"#b@\$j\\o1L_GY]F>reb8%k!A?W'7S7g2GF-4`  .`s]H$2KL[)e$tW$4%(E1T+go"ZJe6N8?ftd'!F'i(IooWEIOCo!F:g1o/9LP.M+R`r#[P.I(-S"bhX1mGIm!T"<V39KCB'_C3i,k6L=8knE[Y8Y$j5rqHLAM[K/h2R&2bp&0Nt%f%aG9lIc8fWNQL/Lq3ZEWOkO=r79Aajl'^a-T0ae(+-,.kgTlD7tM.cnqSTX`55tp_aZNQM&k)?maA8L[J]Ye6NH>5tPm0o.l/SWe%<(9$pSDml_9JgoY)\SQn6:b_>TY&5/9_BmY->iD!@n(W!0\2kS!928^B  Jd%jKS?l+S% GiB$Bk(N74jEcJeHF_ssI[&E3T\R)NE0iqRk^c9>t H3MKKH0FU73U(MU&V\IW\F"A%5";[ri=#A`oPY$=Vo=/%il;!A\*D8_dHL%6S)Kk2IIXBBY]3s9F)H!&$ahAOhS1?18SY.b@WX,.\SJEfbI!78Xg!U5(=N<)iYWOJRQAEIi%s!#CN_[/ 0#aO\7@2jepFrO\^ToBUKf@74VT_rg6/_:kZ2R?,si Ks9_oZFd:A/@\^r'@k^mr'6$KICk,F$;@P]1H[fZrfpWFbg*,f7[Ln$4m.+(;3i:]/A 8#P&fU/\ZI*\O@Y)ai64fi"#_G<@4N2>TD<FCfh&NiF"0Q@F]n>lRMe-o$A&a=l9JWtY:;*5*L.>'rID!qop(R=f0SD*S"0j7Sh!@M@HWkOBb+QHbL["*.#eq3,j;Ri8sGq:#6JRj)Z4?m(WtCZ@DHo>W$<(=mS7*dI :.f$X51B9U`"d'QCCr7s1E_,GfqS<i2%/W+NK2s#;;t]IILa2[/d1`W[FeV14 jQ61aU,_.r#od,%'0l`e"FUKO/FJAiOYKD(@1UWC@s@,d4n'Dg\*_;/+*rSon#pdem7'\Ss2H)R&XK4Gqc0;V]RAXfmJU:)mIGA)*[LB5jnY1FArIG=.%AAY)"<.ZqopOfqcT<sBp@#0AmBA +hH`gIA/= %LL0mb=P4*rN X,8B(`7<eAlZ/i %j$e4T<EVEqJpV:FbAH@.K/cpAnO&5>)N4Q](>[:4m14*k/'oW&g")9i>F=mZ3YL=">B$=T1O=M4Y@AdaI7\)23KEcM%-B5cQ'$lp]g\1LLm4Do'I[[+[.KSY(hj,[=A'QAHtZGI)iSB8.O-pDH:K6Nqg_AY,aaeWo;9&.Z6!lSP8$<M$SlHA:C2_Ns!3cJ<EXmEA"O+[qEm:2IMjfc aCEY!nWUsen^1:r3QKdp+;p,P4q@42iT4-h,X[Flksgt!lW^j6Wk7Z6A;J/'04NoL.ADW>WY?%Ucf*l,m=.J>X1(+=ro)$hWSRY<[R*ESAO@kYE,+ZE=B12;UBgB[r.`HektD.RXZfAd=6tMIr0mkAgXrBbm]%hJ$Ia>?]p]>.5>a;8!ZLoc-eC(KB?3(+^o^to+Pgt:LT4Y(A 70sos!rHMEpW@T [=`SA-,jTCB`(HbKgY(!]S=OiPMRDP_kLd_V\?s`^* a,OXlt>i+6Le`,t'^_t[@1,q:dqPA855MEc4&m65\1j3n.+<sp8IH*CT-?`Y20$k,b;@mn'HNlA`giV7KUI!29;YA"jZd7=Sn=nGB&`+D=Y@VMpSVK/cYlg'hY/[V$i']#t(?\2Y=s'AnDPf>_J0-V 1jej!PM4LYrW],HA]3GAtLF*c%NpR#eAK7W@.CD08 .K-4QeTlr2A\R#P6:t;npdCXPmE;=M)H.Ao2ki.Gk^X7OS?jRr9I4D cg7U]'e69-f-Gj'2(h*.js:I%FpTdhnfDI MNLcQk7B+XY\AQWZ.M;&N)l^W9g*g1)O>cIh(t]l=:g.8MNR[^^HpbAEKhN_VK>=/C]'e@TKAiigaOjofP"UTKJ4?g)N,ro=C:q:<=Sfg4pO#BtfCrk^4*<$M_OI6>\V)"m[8?)=9K.!nH_\@,[J\l&$o4ZS+W_32GH\QKWpRSPo\9ST>,*YIQXj54\O<K@R9ocIYA#a@n!X8+IUq'Dg>aWT+KqQg#rCIpL%:/^A/Zk0!&Q<q;0VN7$2r`"l%Rp"dEe3+4,;AIjEm'f6&qljfXjQEAWO^S?;7HQ%*)0HboA8:WLUpX%dRANd:UE\kYPfSgD-C\,dh#E#F%!c/oYfY^Ho]#GHD#;ZFrAk==(c2Nq@ !(]/FTq.8Wmea XJ-@,.X'9r? !LB&arUD2Ai;LjC*KaIA:EEK-,6&'6Y)$jYdf=QM7Coh5fVp]B#/(E($(\b7"rZH-!sAd*VRWW(c3F6 :Jl;'a\."VDJZ"NsMr:30E /]PRT7d.H_ma1tsM&UAI)q!jRH7Aio 1=IANt.Z#3k[_'\3\h;s@nCH/2T![ZJ:aBgUkOP'p4pEPNU-rAGAk,:_+nFm,:b/4AO<b+rIA(.kGt2b\T[d63hjELNXIVqajbG0:HKY+W>MFDtt7ceOoco(0Z9$o:1EV,bq!hT7QjUBK@FRVXA)b#FAG<;c[Ad_&R41&&P<CcTR'taj]EF(fCsFb'/$Of?@1M$!(.'m:Kb`RAXh[X9IHp/ ZG35b.TZjN*!hb(6F+/qUs'@A04<TqGD?%+3jI3`q3ojQn=%^]-PAZ&m+QKl@57 )!p0>ik-#?=YWgjc'Y$)47J*>">o<t:b*M@6a!$F=Zfco2fWiKB%P,_a58kf)'UU>U5nkr'tNTC&bnc,nG*!W5[`8sfC;aF+tTG8t9>1jIf@nOAaEr]DU$chWZ61 )fB4In+i<.]^0af-pJ/C8RlP(ZA`\mP;T4h"c[VMr1X1%fmdpk)4BF9#i&*WbY+A OG;2"V'LML,qI>V4P@U6H\%$lg+D>=B(I?-Q+-$Z&+#mL8f UffC2&RTX"hk7eYXi,55tjFO41th)'T*cSD/\YDiRmJ&4lQD]rrF88apB\qZ[Bs!OX64<PGR$adA:GTfT70q[W*X^<0:S_aiHQsq2%tT3]HYs%IYU'm7Ke\Jiasl258g>L*9lPXApK`SIA49YYMr/D;%*1]8G1j:A#o*MP?N.+=4n=(fW2KLhMD)CQ000_A%XAa^n?a1!ts1sg/V7Cp-:6[fI(YQp*i6AJtf\):mj+)`"[G=P9<V;;`KYh2jW N>FVQJ\H"LDYi/<\I#aKdnn3,$eeltPj#iEJYG\(R[*.s&U!KcS).Vm^tr;gA$kc\P\?=+AhU2%V<_Cj/KS0sZ4^QR]pVSZD\:is+:-GUH8i4HIJj7B:tT63-B_m9K>ChXigVt\MN@BUmBDig5A)4?;TjAPpW>6Ab(jdh'\!lF&IH,AN!Wbq <nI @GWt*"^a%HP@8Rf2!7""d4iC"0^"m=kQpiEEZ(/lr7'r&;@2IY B;ZVolI=3<cJhn%@39A4G<q##4n#j(Vk"b*l)$q=U3>E&=ZeNW6:ci%"_Krid<\`No2Vq^]KG>RW'C63MXS1o$(jWI/J>Xp5=N4Ns2S4d33ifOM1!A$&@4VU$1&#-btCrgF""Ge^MR<s0(HAAiJ%RBcKkICbShQT/W6N8D*6.[UlMh6nU"YgB@FZK4PX#,_o<p?HRm7')7gPW5QV\aWA_,h711$_.0nhh@&+=-)&O<>@TD6)Almk!ZgqKC8OgppkZJHl6ZL tR#n,31n]$i-)AO4)LKM?<K_e`hR(=^5@tmsQ'Z+<'#ZiNL4%[iD'1`01cC?=C37=KaO<<8?.A71,QMVZj%EEoZ]cF".(ta3.lA5QFllF(HEYg:;4MqAAnZWKqd agd>bVV`b[*A.k^R8 9>/ZV+pP(XNi),k(\X F2)T9;*?$9K"-l^#K``8m<@Rd'\LCGqshA9FJs[2Nqiik))Ek.M fgWa[":])lE ^igSa+'4FQ8?O*(DBWH\?8L1qXY(h?k,=i*/=_]l$%d$*cW+5KP87`6RF#c,1r'K6Sg2=&74Yd@7,b`4"95bD(e'UY)YR#kX )A*9.q0sl,j)R^(O'5kP7!jMprGFM*!r5A]BJ'&pkPdeO@Q[B++1KEPLJ0`1MbqoS!GgCZ]-)aDiol)cq@5bkCAn*@8 s-JT!R*mo7PX'&]\A&Cm)F8!1+a!rpK6#dO8;0:gC$?XEb6N.WQTK;cS%KF0*mraSTAP-E[aSVO@7>5$1E##aD5&,aIZTkUE%#9W]C.5@=8(/<XR6p3ksfh)NcQH^pM?s1D^4XKaD%E7f>KHW/t.iDZ]QQ5I=ErFf)HqLV_J)#X&FbIh*QJT[A_Os-/#f!Qgb\!KArLj!UGN#9gl&k3*X3/g;:n`dY-!Y&#RZG8Klc+PSQmQ:e\BMCgJHQ\Oi!jVO!-6g@A3rmb\pVq*B0@5r*ktX\BAdl-L,@@GjBGS7AO^.!jU%icc-^+@!!nTN/E#9)1"m86qQJ$)i2^"<E;V-I<Q6h@)QV4pQ bUcFCU>e>4*h'&'=kETF-3I(=5c7,bqY5Mc5c,'R!n0hr87*phBM:%t(44jM(!F04pg"-R]DIn@"d`'A4##B;X9d`,R1S%n boGUpSY!4helQV8#69MQRj.(fRJi<;'oIhK&Va@g*eo/k^3O+9tOA)V>;gZ*M!CGYoA^Mek(+p0M7AY9ZY:sS)&7Q+(h+t.NRqX %`1)dh4q$.Ib7s ]SGKn[Q0h]mm+G3IUS@/bq$C%<#2#k9scGN*V$/6gL!Tf@.FF//.r5gBY?9D[#mGbQ+paH4rlVGsXXBqJ-E.ZKeP0AKQX(mPh?W_l.X\I@UKb"rHrQ3n*5nk3L_jA&4`@SkL/4f&,UYsrA1\JU75X `<2QeJ(4,(s*SYAO5<-tNh>V:F^p135lAmDd"#FA2_U@raXOmOqjT&=IdAoa"88UD_5e*=7Yib-q=ier1/b>(\b_?%D)kh(A;A,9Y8ob.WQbi'S@QsRf`%C@%F]qsbq-e<XP661H80!Oa'Z<\1;4i[?l[BQ9GG6%Ds'HT\_`@)4n;H^aCG[J?$^N.)sEgR rh5#p7bR(A!8t5nT@c$0eaP35JL*U+A`=Wb$AgWhm0Y7)[]j`,;\4Adkst[$7Wnl;M_V?lonmaePN)HK5V"g!nQ=`"gpf<B2U@YWj)jnIelhP8g$6+g:Ft&6jV (n'BmCD@t$Ncg7TU=fnRLC!h3DFk"NaVL*6(c\kd%Z>&il3-&s/`riH3;+8M7>am<sT.R>MpJXI/XoHAkPKpXJU71$-'?>eo:XbD^N>1J]NBq:Xj9aW8L4"+<Hn?p+tp$R.>\f8[r(Nk3AB2Ca3:9<OA"(`D9l2EmmQ`d@Lj#HskG@PI5F&ckNnk4e>M>>(>r3ZP%S7K:Jh5'_)JiQn"2_ff6>#0K/hh2,*,dUbS(UhFeRsr"ZO^p*qM'BW9p8 (/EOjJqM<[pbme&L`2XT/b&$ 4R[GI8.6ReDO#/HEA.2Md]DH0<_YqiF;]mFEX?12oq,NnE5qIV7mM<hHb+PZ`GS#rUagL;-TN?lI!kmbT_,CZD+\'*NTI/%LTZL5X_gKd*DRd@Ve8ZG1#fcmM6;Q'hFN(@+V;9j%NC3 &]ohb&X$Y"W[/'g0Ljo3lOIDQ-U4%%"#?]g3:dqA53k+8tAd!aM(<N,7-Y7+'B0VJ7E6B?MRS&Zj=*ZU;!S8a=qA^?g<?<C\AiRF+q0\?f#bTcWpB*4:`7JAG(.rMHmq*5A8>, k+a*)D3SQY9*9!Q?=g[m!<K,<]"3`"(l:>mTe:jmq&jAQeCad4Wo^c34ttXHq8Bf&_*11<t?E_'NI6,6N9/! 2E$"Ctc-3[F@`:+9f69b1o2"'!l`o[iIP1rgX&9r^]a58n]%/Zo^XSA+llTTYEGAelN4D_h^,.rndN(=&AlntlF9R:i6gNf;#E8@Ni*:3]*Y7L`PPFM">a90K"$Ti7V-LCJ$_\XHOUe9';=>pfk5TFBpgJ.\<BA1RhL6Y7^tP6=3EAG=JlK\e<Mj^a6c-[d=VG/#L-djIrjB._(/KosS>`)$rV#[kDp@M@%)Z`2MQp&=kq-T*-T!`.D7*e*_BM:oA$`O?/,$FB>,^7Rb<`>?QNp0&P?HH\6e\ZW"+]M.N3GfLPSJ,&$<b-a.?m4LEMbt[FH/.LX%]!'8S<`kL7H'S;%Bhml-O%#A.AQ#dl$+PXE8!Y!2%aCt),+ NK>UHZQoT3qk<7r'RJD9oFYcY%X*LdK5l\M=VVG%Cd`1V;0AV:/@.GP@&;pMo/%70[36V@UbeR/bqp(aA;/8, h3cYKhm8-<pXs3Jobn",N[H]FSfKenq[78f#4Oj74\:L[`O#i=?Un2tmI/mD=po'i-,0oBQ4JWjP=9">!X>`Ak@.=KF/Kn*Lr9A2HBMb+Ma5=6GlaJJ7D)VNsYn>kS+[1W!rF-2=/LV(7ee-LM%)b]Xf@?MknFlJ?6LAbX.H7toG'U*ZhALkX>'`/Z:O7Asj29LgT0&V!+/ABRn=aEK+qI\,oU0sMsfo0e\[YXY]+Spbn67HIJOfCgJR3<43tZC1KnJr=f4fr:.#KRfZ(M=;!k;@HT :/iZ_H.HTPn2VkAnn)s4A1'Y]1iV5#,mI=m`^(4@+(`^%-ia"oh<N:@Nttel]\]Oma*LdIdFt+O6aV/t7MJ0c&8Q%M`attI'R0ij3hasMh]VJj?"Hiq'GR4MWn5aOt-K+DWJ\!\mn[?LXWA?MRs9 ][%Q7+=ZfN>6!%g[_/D&;8!':E1NKG&4))ARR-Ar6=)@Q &&)>/f/=SLQ_#,efRaiKj:*4G.8Lc*>*BkJi#bXoHQr&^=aXB0\-m;?\^F_<ZnUT1W8IsdIVf#q,^t=o*%PXj<dN5W40HsbA.FdR-Ii&0All\>AF?r5oA\EI`X23a=8RZR3LqN#m,VE5+C,"Lhs*mrmFKG^(4ffII==VkpJ"f)T*qO_ja9,\J"-Qt$"AClXSUTAc/t[-dR/?&fV0E3r-D% ]M;SGmMo>h[H`iA%a@.N\D+eh@*-`Ap##HP&$bIY!-Cm14pK7X@T)^%b'bF7M`F;)Lh!SN9FTG*dY_rT\pK;8A#6lINMYs+JGn9Q`?-oKWN.YfE g^?#n@ZFI8"a9:sc5$tKmD8o-;CRJ92+Y[3cAWNS:Jf9/T1#Y=F-64BiIRiQB3qCbIU</Rr)T$iV)q\ r/cAdd:K^;WA?b[b<L(CpHRk -&%PVE8Ng..Nfc_k\Pd3AFA()<3l<4CWAs FcSbb%$j6WEZ,_)O(?(&)>XX=p=DA*/j=nrPcOsf`Ja18I7R=_(g5mABgVD<M4EFPUE9+ *>3Y&*>JKP')OWdVkC-fRrPcX0KMt2 C`Fol[nRllZriSWs']A=LX<3RPV`?cBfY#-A:#F?Y[$Y$5.@2sW7T?L`$;QH$$VgYkr4B_"eSC[a36dC[ cT%*a(C%<%:X/_R6Fq;YBAgd 9)lUFXg$PtnA,"EQrAq;:Ss+tA"tF3VA^7$\]/!*]2+8/ ,0ES-1??Wq[>_$`;2kf8^lt-fZ>h[#5G>j(BNG.'Xqk]?n$cLOOLhU2F?W%MOLM%JsHp8GJ$VO=3h3P/*fp1)hl]iP"32CFGM@_$,G!`KHh#d0L"5EeSn hj'.3Y06q`#_%Z[%7PZoZ;YgN)b^@&'Ym_,_l_q"#)gK(#6U`k7W,ie/W_)a/Q;r6bl<q0EAGX:^.P@Ol')E^/@EPPjaHoM9JZjC6+ki@J^\q/'#sRa%H1WkHEG/+9%KWamAsUdU6rp'Xo)@@E$Fq"KC`W/jLk.Lnd'CoEcA2N36E@ENT8pI@9J:R]^O3oN5YY,^ JV=6J\bmaR8*A0)&</R(t`/+(NC[(6TD_'6Ul10n6Wgd5b*/A1`$fciafJ/@*4UY[[0[N!6?gC389H9]"b]<ltnA@.QYJ#X%'hq]&BX;s5d36g])4Oa:[0+QZ(MQRmsKS`(r%&mG_2NpF"ATY6EqGF68OB05o0k4BU&DEh!(.7j2k>-:@2c]KGGY5WW iKLZe)WWjm 0:;Nm[dF/$%U"f:DoeGgRmY-Lf:tf:a!7_>G!lAB663CedhibAW+PYF-,_"26:NRO@:B8;>dBk?Ej(%NHQ_2:p"5aR#<:N6+]b3J4$31\a`B-,B+)M\0Ramq(XMV>jNKA=Kp%lXbN+E;#EbCHsaX00jg.iAXL:q?\L#1UFRm_%K]h,C%9mo^h*Q,14#^+Z@m<FI3En$:niO.5;B6l,5b]Tl?.!cT1].Ke7SeQAC7AVM^I4U,*>8]FqVtFL\BH.m$t8SqGpc?nHLlMJ=@.SCkXhjE5-lqg= BI9Rq8PSf;LmfJTa>jBUaQ,p\,7V]"4jf@dT+<ft+"3 ;FrUmt5`^<L=h55./CFW3gt9r6ctRCe6+3lZKs['it`J5jFH2@V.7JA8E?RT; UQ9A7BoM%*@2eE![bd\5p9]CPGK;i 2EDGr4(Y_T2X5mef,sH0+Ei3*gVD3=Y.@),$pWir3YV<\*)At6DqAm``JN/6Ld$*nRPSApMdsB^U'RK_tOiEle/XZB5E>,T(r^B#)gk3*FR;'*mq5!2)@N0AK/.`^1tp_p^VZ1,\O3"S]qO9eNQRo`L.eG?/f7Dl.2nZYpd aW8o03SA%ZDLNP3G8*1<6:*hVoJ=TrVa&!t(I+DoLW6h0tkmAnehjg+>UJV ]JTBnm ;hN^l+)S.CG:\j[em6m>;TK5Y%;p=>H.8ZedEk=BN?\\DOG)PP.S-!lT@#&HB9)FOII[CO(e0&JL<O)gX-CiH=I#&q(dAH7$5X'%\G.N,75ogEeb]LmLS0)^@=qAgZ@e+De!<7JAY\#6N2oT"=:g7k\S]?WJ6gM"]bJ.fZ>LJ7V=d(Lr:=dm]p3"SL;'*_O)"6V897cWP$s>Q*<?dla:j)rV1p#KDA&qj.m>I\G*JHZY6/9c[/.!:31'mibAEiEkRa_%]d+?)bna.,ZIf)cfc<L8j%9X.330t7\oUlh%tbH3'kF`'8ZLk*r,0`ZTOo\]AB5n$^D+3l]dNfPS/c't#<aT&Z=kd3Lm\)s+?P@( /^Rb@FK"Wki]h7XBNFMt)lh@aGT%?CqHV*`==Hat#^4!DYTn@Z>Chc;gFc.e'[)<tm]r)As!Akq<(]9<tiZ92SA>6.eV#/itVK+:Lr0HC3$Z4*oLk%0mYLj3#DU\4qWqNBsNS'_B9d-*09U9),e'>bYi?#&dAl\X(7?0%eRQ:V*hDeI84n"X1a/N,ITr5/N,S2"3Pm,k5]s5gf7WU`NkNrdFd(7P:,)(nPD=jH8c4ksI/<.WUfE=_OF7Up4H>qic<.r05nsEoeXfgB2$ ]MVSj5Hj=GsCs"\hA1>c:9Uj?%[Y=<N6*`QE*L9M4K'k@j!eYC/KDs5AbA/-ATEn5F*tG:KEVSKsbc%TMC"tV]j!LA[8EG*-i^TYY),3hZ1tlKbf\(Y/o66iNjIW-_g."piGg0kT7IlVDo1e$ai'iJ 1k$Z%gJ 3n(ZmD1X]IZYZgHj_"hP-a)N5FCL9c@s[j-9SF-RAeDU)eL0oNT.\nXZpe$,ZHH-:ch:.6:P"cL(09m#L9&g_F)F`kLBfC+n&`MaONb\L8&'XOjW&A5V!9FqPYk1:i9*J@<RV.7Fg8dR[!($0RBG8JAjk)CT^*80]\.U.Ll-<hW(HF_';i9Bt>1/=4<T1H[tm'@W,.^J2%)fUBk+SZ(_5Frl4B;#< @<n&qeFD^ 0=#81[sSo8@@tWDO/S#/*`Uh+NNIRRONqtgb$>jA^TCVaLePTrY]2IlGI?SXRiA\0loHkLs?`O\8&?<>3!?SM3AmB)W>oRDU$[2k`7_>Y,a,+C.e":sEb&fTD0EA5.XdX2#ZTM>$X93b37.*$+YrFTorc85839WA[A:7?4>X`VIN3`<5!ZH\h^4pFA<mZ@[c];\6MPj.#c;3.3@6c;<p\gQ9IAH<i;G+'l_8>^JAln:8Q'HFG`jnAnCRf`8WHPF]]$k[B#1;LHW?)W5IS4@C=O$4E"]4!Cl2GpA ^Cm/tJ *?`6pLMkVdd.iMlo#[/<l\b=JZN$S]G]#Ee&/pd.#16olAklO:s,1e+9d2;SA 'j@VP3BEFcAUh_9Y&Y!cnMsh3>af]Jc#Jn^tn?BefEJ]jMMkWIh`]sha.f+e< 80^_)6 `G0=YPUDm_Efb*\&*S?Op6kBI;Ae!C)-(DFT<q_<TF=+ei,8oY5NDA+1r&qr p?''<`Vnp;SU#9.>>2iQk2tOftCQ!M8V(>S=@$RNZ*n=ANm2B1kN#I)PC\G;\aEHjW#XrRo">"YFD(`pU5tf)_T^8SLUZqU#.2C6`#EpJtZ^KL\.(n/&-0WWO&mr`1RAF"&LtQ=`<h6?#:aJnh@H WR,p@l@+(&;2e]NC?cj8e\'!Xi!^7=dDl[2^QfrrXMM0#aNVXB9&Z?02.^4AT#Ln;QLCcN5P&45B^cU)mg.,IJ'/gN7?>i?5opDmm`Aahli-r,H*1(32^Lc>n<,]]-^]0GRn$l5j_N#hr4;*.e6P?-$+Sm%PU>9as`Ls1-JINC"eFPC%5sATQF#,s`I;SRFCN@:- C?R)b:tX\:iVpK<`0FR`].7k:KmlBjI[,Kq"@QGa*QK.mkd$CnOp$5WW@GqDZnJ>p'E4,/j[_hX"1@)O=A>`-Qb1Re+b'!': $kU<W"=s)AnJ4.:4&'S&IY%#CbnJS5;_`!42!b\c*%%+"@F^n]5PfCjORH.-^?_t=:Rd;/lb=B8SjC35 (?e>B`bgrrJ`&"9V7e/)i,(:I:7j5gh \,&I5>&h/^C0PctX-3s'VAdCB6sO(F."4:OL50H3+o("=n.AU13=OsE-Y$8a0jSp+!3OS0Kn%TY1VjAGI2EcnJ/f,9?RRWUhd^AHAcq=%NF"c_O6\5>lK<IKE"!6G[/=OP!)K]mIYCL_T*U;BmBtV3[1j%_t"OI"c@`#Ib2mim6e*#KG t3Xpsq\MlB>L45A?.jr0B.]XRc(?7?6MB0P1VWEc1n!'/N!75,.=!D>92_FPLHmPDB"qrJ'BK978B3g.6(Nh/-#\"SsokOb>DcfJ^eEa &.ccAH2_bdA"")'I)7Y$3o%@l]RPrAogDj;60"LXpE/VtkjV[%4rYh0NAs\a'_0/Uc(iVb_i%<A$qs>?>[GTP\5@9%iiiB6r91qf0At[t$D-_:5^M_7g?M_ZQX][6OMK8"S,Um8@S[Z3M&;ZYT)N&_LA.=c PAl5A@(\5jB(8O!t% c$s?+Ga?,JjP.,#B_DI8,PPjK+!e"^dqNKdd[jHL'\/_eaPifs[2CiG^nm:.gjV`&qak@BJ0SRVSQhtQQ2[A]?]k)o`lln\^4I>6*SfJ#tc-'aqt7+?h-.Xsn!B*AKV25a'NH,j&YQ[?)@PK8L'PZDPtK>n)+F6^Nnj,ZrfpjWg:H+_*>/6K_]a?#mn^dAa:8tDLa3hi2_bZ@rk?g9%a^s&eW_#k!9Sr(mM0CQ2Ot`qnBfR2Pm`8hq6"g#E9XNF)th%(IH=^FM'bso!)n7Jg3o?\6mQ#jlI0GU5G+#DmC(V;7@(^gs(t\mJ*V&\V\@Ed[b2[[>N^;#SIWj#Af-cF!m,=1Hh$R=VSclKEqnom[0,QV-s%K#!g9G;4o@c^?;D,jRFHaaCUh-L -4\6TX)`\IB4:4(+Adeh9CQf=t0(tO>n;C@Nh__?Fo&Z8]TO:hMf_+B D8?+=PA*bE<M'6@Y!^eS:G`apd(:5)Q>[JP1=Hjn aYs>SRl"ITj4qL)ILm$i\f^Kmg)atqED,]34Mt+IAA,%Y ignFm3&[4rbl6#c9+aW9/R+HSXkAA'.Ij2>1(OJWF24H(SBY^;V1%&Ora?U#(mr]de`@&QJ&(^Zl"9%N"`t_[]E98>c?sGjo#;nd*,kW=>r_Ddt!Q,Q25FgH72eL*fW2f7E+<aAn<gZ"PaYaP'p* OE>[hihR;bqmDooi9`jiLm)PM-(A:i=D2%P/MB)k@'dTBLX@:EKK4`A0"A)`1LmBr U$ql2)AtCmUsDiAVAWb8""#kV=b65,&CX!H(Da7sdd-<=hHHo03,OLCcC6* \?(_T)47RfWfPYc_eZ&%1lj"0W/?.=J?M%orZT5<qA51WSnfroD)`ccg-\K:+HQ'h8E_ALTimoeA1dXFP3 CI/c9_0%J]DE=(Fa''lR4<9B\'5s.2Co580Sri[A85n<1ro/"#)_/-A3*),@mmp4UJF4'j4FM[tc6Kj9&DeB<gH7=1AIN3fB):e@@jo\'-teO;2`M!P_Xga'C]U#mSpV(CedWd6/:\A*k6_3S'ca? $hei3j$_8JB-W_[m8oDjQ++m5lj*moJH$3\hf_<92:eg:^?Jb></is_#l&CL7<&b_U7Eh,c]4B9j*!,_5pH3<+BRc+n2 'AB])MT\eb\-XF5X^+-2DDJ7 FN&ra,T;\97@l>?9C;<TElZRc'VNg._V'Hio+fm]NosF&s(R#$tOfd=LdVt X?8E^W /fMI41;Cj]e9$=^m3<m?O:%11F7P7h$gleBj+0!^0=;BE+4+`Kh8Z[T[6prYkF%]_a5+-pk 4a/$BrLkY>#*N S*4l6*R_70:fP>"mlEA-#DPXVdfF>A5JJ*\Lk&!.@CNtQLn74,gN_NK=h'I`RAc'Kt7^AslCRjMGc'j+[,W6$LbUJ0@GLd3FK)]81&P8b]DT;@^7??c:NA]8ptTrR&,/eX)I]MK&'q%TcPe(TaV-er!'3j.iXGAmdG3$GZ&G$')>/AhbOtm2T@hNq\\sfps -L248n$^ALP]ho[@1/.ZZq3IWG!*2WXPs%[S-$**YGC?($A-;.G-NOa>B&)A0_.`Cr'QlM_=>GA(Q%Crtn_6Oi+pj*iq@eX_As'nS U[LJtt4p3Dn6FHIY(1I%D4\>r78crA)<OVqpHbm9k!Miiis $I[O5\HVS6"Tm0L$Z;k6AJR':(]^c&C2)_cALI:8^P: GD+]r7Qm<mf*?3@Gq8 fP%YFr=JB#3j"[I7FM+A?Nl2qV((8N!ARRZEFm.Ha_C-"l]fTJU'-eD/+().mkYJj G/":CE2NM_ngf=(frO3NW4KfN@<%"ltQ;6`MMD9YUL?YdKE86Wr-3@WP->E4aD#\hU!][mh3)ME5bCo(OlVLEU35q (fjKUlBq^qCn[%N"WAV_8Tb-EA3IM]4S'-5\phTYY3SFsCn'( F<TWXKhQ&!Q,Nj*!o"],M5_YfG6*EHcZ=P(SiAY%1CZmnIfeA;Fb(hIdH3WA#$?mHK@OFcrF<.pBUQC46T2'?qr5`>l<(cLB<p:*jo5FDVd=6+NB1>=XG#rVjK5P"b9%bJee_/_AL>D_Oa;XZs\ JFHRP"n+.#AY^.$a1p'j+;3@Ho4^)W(C<;J+PfKr'DW(qKn/L^lB@X`8[9\.$#i^,)RCE).`gMXC?p_jh`.d5$<VE<n`!f&b-J2VHDmgXs_2T3c<84Q`r("Ua"om1.F8OWPc8f.CJ=^n9MC8P-50PhA"P2Ibm_EWGs*HNR)+'Se-;#X9OC)B3DPjO%dabK]:^VVEmM*6_jG)P\IJ"gpKm4 tp[^N6;6!FR!nVFT^<gL3%$FM>Vb4^h\b;Q5LY&&7"BKkn ]$^-`+S9M'=!f:Vh643P-OraoJQnn*@AE3n3%kcMt"dh'CRBK',l@6`?Z)M7_1<DOZ`[K3h1<.FH?lc9-_:Io&d2Ta#SDr"_tRBjI8<co`QL/Aid)lOYW-Sk%*eNch3K8`<N-]X0)(Q!`HVm $^%LB9paS;qK Ad2t9c<:BsC!g#NA)V2IFnr0kAZN/..P0 $B=moOAaJM*<sqLUPpnHK/E5-f 7YM=[F$>*3gg)].<hAk\,72dH`_2'eP'36F5%pQ8+:FH'Q:;2ZXXGIApr]q[s65"? XJ g&r^=7K;G+?2s&->:Vad("+gft$T3aW]q+3o(d/WcSW:_B2#e@n&mq7N7W09],V[Hio8!6OZ%nP=LjAl"]h1@&T`8XDF-3F,%MD=.Y[j8#Wj6>=8;2nLO`93V8HiB3GYjW4CBdeI<)W(SZ8cm;SCGgC`ZK!$)Z\CM>W!Na/:VK`MA[-YdoS->HZ5Nm+^R[W^NrOI-(c)J6HCC7e'M=-DaNcPf]4r;rTdl\0[>6"\1)kHV,IoaP2\F!PJ2jL1G-4Y?)ML"a:G^^/EkX`>)@_#r$TZJg6;A7YWf+rJ5hec<&FJ@?3%;]GGmB9DmInjAY@^AE24MZ2Sb#(:!ke1J3mU0'q;AM8XHLgrj3<&Z-]l!M%2A5.a<RYhIK[!9n@8QDnJ6=]^OVR:6->f>ZRh!qLr)MJn>>0bbDLRR<[hq$8oi'2h.blNaY .N'L/'h[&3*\Onjl/LUoMjA= FQj<2l4[>JGsCM:`Q:#[QL9/U9V>LZrfl%=9OAtLg3.'eLrH75.:Nm,i>Bd7 3n<2-q8p=?`FM"Em6g_ngd*WND4PtcgT)ecQe%d1"8A_(qPr*iW9N#="aBd8N3bKONV* -p[^^h`/C$Oc[b':)#W3>rBBtQ<;giCQ?/kSK'j.gMK8i>6`c<B'gC2D?tQdAFOHra3TSQ#qX]a8!3GC)j!35KLV,j#]OYJ,c*E-^&OFM[0,9j)sf&ORm@3*2tUcW8T5%c"OI#-tZS;=+5j#0#4GPAN[,E.ptI+g/BX_GVN`/)OAA&phEaYAT*UJ:9Q%BA``b7q8A $?CaTPNVXj8R"#kE.22A`Ch#,stA^Or8i02;<qm+kF!Cm16 V'Or& )KQ-L.o>^h$6rX>,2t#^r$6Ai)Z8q^=8tr]BdP!WAb*5=[J]Fl $c#Q*JPX\^PnSB8BBSZQ2aTH5qT;:\$en7K737i'C.14gE\/ FK$.`6Ps>k@6+l0G^7fAmgEb\siM4rVF?]2X=Y'(4]O)jBFdVQ#ER0=.BZ,scQ \;l`>Sc3Sej^,YRk+ka%l,eRoANq5+E*$=edWYdJo<#j,8]YIK+t/&6<5.WW2& 6J$i4l[gj.^R&KtPq:+\:AR:cpX4M30_fl77Q*j 196-t9i>PfNLh$/#&+-:tIq__jbj@fj@:.>e?Ysd?=WF`Nf:mSM.0he25-Gbb3s<&#9&Df :$OJ9X%gMm"=`p,(otl8II&M(kn$3M!UI(M\Y'/Cmrl$@AE9 _;cip2JS_e4plaNP)S(9;76Mj]deeSaT.[2b+ZJ1A<<n,>oh_/t!XWI\Ac0#@_m^aT6Ng@0Vl3AscN,ib65]4QoCLg58d)g<O87SsN_-eUS6#nccYZrI<K<P-+QX>dO<?&k?M@JspW8GM2hG=Tg2q83k@ld'+:#(pfRr#09qc3Ue&!PWg9"hYb^>(&&qJQ=J!T^2;9)d+0WXp@E9/n188"eMrV4`Dt06]dY`pX;hE)!PlT(CAa+.MNF3C@CCG<71rkh;PN]Co0VcY%biWbOt]tLB"__IU:L 0? 'CS5ZlWbAlG#$"Y[7rZs=4UiCPKiHQO[ai`Ocl-/R@a?FSFaEJ>%>:qhrPK7O!qS;#EI\,Z(A.nl>r:LY2N47la4e]obrh@0k->>sTFQ6L6T*$AKBJ43DHNtij?HMh r#d.WLOCC"@LPX`-_q1Y3bUHA0<\K^k0nS0O,?f[lM'Y(tBM$2A4Hq-F!3X+,X\"MH?M/6G *NTRg\T[ol5"V+(T@tf=a5'g1(iDWr?9b^D12@6PX1a!C3B.M%PmMNXI:1k9NegL(#9D,T]c;ZhqWj;:[CVs-nflL+A\:7L:1Wk=1e+%4`J9go(4ap9h(trBJaP+3!]LJA-e-lWMp42AfV",>7<S;04qKHDNAFrk3<ATKbfBdKr.;(X/UFa]<h%-"IK!t55i369VY_f?@=#">(5$M58/_UAs'9m$:,J@Uc8jefpVg@PNXiF/b^bV+],1];Um31DAqk"nE"OR)VR/^nN `giO%X 2ZX/S`&rr5\6Wo7ZN3^!SN'nq+P!$7S]H`.(&gAs!?V[6:GptG1Z(Der*Rb]1^D--jX(gPGZ4Le<C&.N2/no<TT"lV9O`*WfRq%oBJ2dKVhHq"f$tPUCI0;BYZJiK"^A^KW,D]^3Z:Af&+6L1A43J%I0YCkAZ^7Tf1Z<[H/?4o7eWFCKEX8n(/FHTpPg]%D,]T%d=rD\9-$sY\O[qKGVL]^A-VVD(__5%t<H.6mlHXGX;!jg<#/p!_bLmP[dV%Rh\ha(US> ZMP*IcX_A^rOeOC$To5YKg"%r/+-%h%iQ>^0Xl$\dX@I` ]T2h$kFhcQsb/VjV<rF]D$!-Q9BWfQt6V<R4V;2B?$LC4?G#[YS3rt)0IdT7*]b/Y6;)pCD,r!lMFcnng_+hVMtjD_VURmL3=jh1C=[<U+Oo!^U"'PO;f)spBB(@tgi4fSQl.%]*pM-^5F.ddTN(*nS<9G1(=mr^b'b0Zh+B*IDW#SF;NS;#F'q/FDV2^qsA1cWZA< bVr?s2Q4@=0!,XXt%/Q>&g s^O,."(KI4h+ARfselg[`Z;WIeV=A1c-jfNF$s6$/3\ek;Jb PHk-X9WpV/"JMT1r4/iV%]"UDg7%f/k#N\!ioc2M;CN1:4!@+XY4d`K*&/Cdjh)KO5@YDm?8l3*2 cnSV2KYg+-S,?NEAF'7o8gE]iVnYNXG9mPb]g [j]1(>!(l1]j5`7E)D.th\X 8?G/dOP.)@)GRSn(EW,,<<E; ]p^+6%sP%jFm8W(aiPTNnPhT%YAfEk_dkTYt<Y9 CdY2%+HA1+3A,G;A8UmPYDa8A74.'=t&B4ns]lo6[g#[UnH9#phl!^;(ClNtRppFs)f7B+@IoNNNSLpj)";cNF"liZp5^gch6#9:03,:"BMC/bJD6LJVho,.^Blr0l$#]#oA0f!-8;?iK0ngCPdtjc8RDUfa9Ql'CC-O>JAl,,"PthC@,<H=2#t@1G$5*.'#0f1m@+M R7/Vii`sIJs+7gp%f#;*I'ZgW7$.^-J1^L/a+P C1E66fA;CAZCoSaR$%q>(Ttl3]S+2e&%>.j:)0#[1*kD$]!+[SA8T@jt/^iA,AE@YQ*a/[BPH+HQ5 FSG*S:,BiW@H_MdBK76.<-k75-AR.;6"PD(%0INhS7ePls57q;J1`.aK-E<pjdAsd'[noGf\N5*gd`Q58n`VddhUJ8!B!AlK3_aT)[=Q9O@Z-c#scjPlR0sN.A_HL-YZR]8O#SigH"f#`mdFR(je> 7_W.mK"[VZlAEPkb7kI45ibQA5LonVs7Ds2_!&;r%G"(!o'FPDT)NAbg/.R7FR[ll.f]#!1eC<@YqiCf1q9YsRA5@`^%EfYcdCjA!Y,6 IK=VOm&sLmA1kkC6eC!*0&e+L"^)pdKQgXAaXk3$mnG(43KDI$Y-pD+h>oC9F`RITFR!D'oX)=OE^eO1IOQ>%Q[5QY9O#ETf!\dc;Z85KXhpALN#4g*.Y q`O5I#XUh*AUb]`<b2#)%OP:Le*<>R-+TP[@Y+bm6n,N?5`#-hoDn']>A[]Ar?[r6tAA*1;9q/EVV<3*>Br_)kk#n2HP9j.8#c+B8\38($=M+';<6e4SL4"1Nd&.O4eVkT@;8;fMXBrj%bWCr[Qcj110"pWRck<pJL9V5\0<b;Etke6AJ5/SR"jpL*=bY/%>p^>qnB.X*cm`S27'f]\0 "l";j(Ah.CA +$R%%6.lk3BPTK;T'aKeY28eQg;2%:bi;5EjP^PlDUZEDQ9 Y%s/'AO?s&+4=&ddn24D&0Z$D>%W#[>&-nAgX;78`-5hj?^GktMm%W=,>KjVV3/a;ik.[@=BoF\+fHtBd3Vc'Rrpm&+PN+sR31AAj@kf*mp[IieK9OqS\=1NgFG5d?/G4`Da&k#!dr3n7jM[NQC>jk8g!5Ie__3"7)/Brqmk1tFUhXKi&q5[9UPdt];$tiMWa'l8mNDZ?Z(SDUH\7N4$F5Wejo]_^J7AngphnD)O7Kk:$;jKVE1\aCRL5aJDW%agA*les"Vk3$0pq?dLfi#2*'S97(Zg5PW*?8m5rjkA<p';]m\r'^[8P-M\Wjrc04Uck&&d'Vh2jDmR$=dj)Ej%8";TE!an2FdC$98F:;kW[(:e)#DFcYkVY*I[jkCH8T$D#%X<V05;C'O_$e3k3 n1m.b!P@3sj0@s19?GA\)b?6&WYl!P,lT7%#)L59:&+J!TO#;qR^rS P^U!+oo+,:%NYRMs<9siUDXP16Ao[Xa^.47@JbkaqD,"G8@_t=ZkerqEj(d(`dhR)<<b3`C*%dGF>hhjd9hk(AS\mB(K?i#AYS)?P[9(bj:jEG' 272%!"*r;tD>"X$/i0A?NJfp`n?dIA9>nb\1TOhZ:2@l1Td?M>H#Q*)>1$@nb[7XhGZKln*7K%,Jb@i4Xl#,_sURb_Q=eU1P<O4 <L9QihGJkr!A%#.p0`Ig$Apq;70+b_*J!g\W5!K"?$A//Ac@=a$9q']]K)C`hBM31TPjC+@Bam,FGfdY0B"'q3h;V<"-gOUb!?W^i@?Y#C/7#r_ts<CDIU6h0%?K\&JTH\9SktiY(S0`.fD770j=gWA)_PH+dP?f!-\I"e$1NORSbe/9:7<M@,?$&_aQe07 )<g\Z"J3EU,L#sU0sa?k3ICK.%Mf2%-*PVR96[1]m#O4"Ra`BAk(H&bVn9CZCs4:8>()+Xo_N&ON(koKO45`8 3pH_-30HH@K3bSIi7U<s&l6oR8C4q7'rHg%;U.ZKOW1BrV8<4)t?1*d:A1Kdn7Rd'i)0YdC(r3ASmaXL-g0 LN $0GfmtP'9XcV2cDU[1BCIE*YA2^d6qVgbWrdgDf[nYbTqo!%&NTrJ37W?G9pR(c_7IPp2E^bY&D3BW2!&Q3Q@BiAB=`;"?0$n GMNEJ==d %e8A([J?LEV Slri:<O@k^]%'6l qeQBd`pkYcXQP&AaAi@#K3XfEKkPmQ]6(Ism':eJ\A3(8Bic+.Zk>W*9/%F'SE7I?]<0rmcA43mj*O#s-U$ZeU;pTV[lYbr]$O11l;_(*.D/A-H9)*XrX;7'c[XNmXb+YIgk9[hQHlU]_t'k&V.;qh9+N %A:A*VSRQ\:VL9 I4L.ofoGWqA\90>\-IASNB= 8?W7Ef#hT$<NoV;aAi4Q"I9@9_VQpiDB%mH<_M8b))A32#_dBWr\4b,[ZBDbA-iOs[(pEtAXCOM)08#9,1&EWmbf"Y1((#hq*`+Ir:UnX,[mhU"nAWSo-k6_s?$,6*:Q&&[1#4=O;RKABmH3W2\jT@mONSAob# 6TRUk9E3Ln_&_jeerEMUIr+LoO/$>s-#@rZH2\ESG2tgon`oM&+9OgEU[T^/B`Kp.lDr(G #r"bOdgjCf?PDPZg.s+5%Gt7lPo"A=L%0cfi`NE)U/&J3^02@-kI\=f0radj/R/4242%X$&pj1`kbhm\F]M2?dnK(T+n'>D75ZC\OI0Ocl0[`2:#: Zd#bWXG[IRSRtj6!r&L/DhcLQ5dl!4n](httJ507Zt)b\=gn2!giP<jo-S!?8p8XM!tbL^)darUS7X$12WI[-,X3ore^TZ`NOM>Z0KiI*c8`dpG^`N -6"dl&L2[%\G/g<?8$'#2j-tW;I2YbAqk.!@#kpSObh*bo2X&&?sk,%f!*bVFjUBUd'$64(_5D"]?tg<#L1R(Ugp#>O<Kng1NAN+2$UNYt"4NY[k&\dPh$H/W=MT83K8F[Krt8-01CP#l7>PPQTp6->6#-SpLM<B37qW,l1&6-RJ)"1Q4:&f@"_:`Gc(KG\=QOsQPeA>^ aqAR#"])_*BgmV!n7:VU%9`j83E$F[K>JBe )I&4hD"DPo)^nML_nKQem!rJDojCaO7hTLZSUFl=^"al.;AiZ#2;j"ICgk!>#E(7p/%Laonf9;qrK!7&+KeKI[`><'8ml`a=<]TBt>!8Tl#(.JAs*i?NWLL>)'sSpV>2qp0FUhOg'm/@8ojW'&pf-\/hYo#-A83*gclkEZ5/3XSRd`Ae\+7d7fN!8GO(e4\qA&4'N pUR]rnlZn&oWCCiG5q1o_"_@3XMb\IWf$Y"b^G%^,rGY.7/1&&mF0<+cf3jW-WbIS ?'-"B6iS.SL,OrS!+"cGX_DQ\V<r\=aaJJ@/4-YL:I'ho /.[V6@POCoDL4e=saZ?_Zeepp$]:F;31n`C,*l85!-17LM,]aZ-nDoi<Mi<5U]A7geSPc>5[6^7bZEeVP`C#W@;XaC^ oK3gF]9iUS<,:J;r1&U)Af(,LV;`ikl(b+0@#YY2s)%`2Mc#ksHWVjk$t2iM[`Z$%t<PbTEZG@kX4e>4iH*!AlRrpVHE5&)/S:sJ[>U)jXMq)4HmT#o0f;Z*@&%-LB([#m3";cEA"jh"_'#Mqn1,q'Lds ZL`b'A2JOoL+5.aH1i5l$H4+ ;*Nhk*gEl(PA^a;ggATU[8!3$C;JLU2ne9)p<$NV&Ma>W"Ak<PtFU7jNFg'Hm5r_o[_ !+Zc=>2rDf28\.($7DnUOGr-n?$K32WYa[Zb^N6%$,I>[>0mN+rn[A#Ph.>M0e@A50.g(%eU-bL\.bSU&imF1^AeY@GC<8qj?Wc"+rls,o%,QLdCk&In%PQnaT<h2S*?31`)"m8=#A2St:h?o'tG VegFB/aFA.hF7i&@bTGmsAl*0tVH`)K8nO%%2IP3Sijs8ZlfUHm\^[_X3V\+OEnd`h$>G_g!)t@O.7Ak!od5-r-9=<$Y?:5MAW\eD(8R4MK:WP?V6P_OUPoYnCW9@#/>DKr%2q5PPP:?)8L#>.n^C#`C*2k=)Y'\?2A!IDVWa"cHij2C(g#ht8S;9<]Hm@.`$]q#0":<k['mLNp!m)(&M:67tG-"DNdfTGrIFqp@( -?<C:l=N*f 7Ag-`/ K%gdq,YM@@L`lIY^6icai*nn<9>;oDCZ^%-o<lS`TDAQkT ]=Sg1M%FMo3DZ5ek/7*la`L27Q$5Ir1q9Kh7lF^PaQGfbg=M24N*];]>fcAQJp8"eGZg61bW^-U&:t0!9N[caoZ>Ib%,2$.:$;o61TtgB$mUmT:m/K^k/sX\R9[5=fk;#E9+NfC,Q;R3LoOgoDW02QOIOQ`M/TZWXX%7\dLI&fk\n2-;A0>3Ua>+&BpV&LeF8_?QUk7er `+MKIMqT7hh5H%Y'!2ahrI!-XC!aDWd gbdb-a7+"+&<$\s54nDJ`k8n"A(SP19r$mM1ArGA\mD&8UK#o0S(@4ph^[IX]@I"Jgr[gse66b5[AEG@Fa61jSLcCk,F7sF+e%\UV[_0`l)S$a<2WGsA2C+dg8lec]'^3l89Dcj8@C#$Il88b'H99feK%a/Ee>Q)%rOWf3kbth,3V??N$H,J>$lPUiA/gD+#!cJ=a4]ae!aD&.fL0e</@,'c)S+g.sIc TlJbQ\ktIi0EJ[i;qN49b-:%cN2EE 7DrpVO ^ (J(\a,=;ZN?E?V98s/^ik'Xb=E<jQh=&o(?JTHsHJ=X>67s+g_?D*&aU=P.n;4EM]Y/8f4qPVAA^7ML>7IA&>*T =LP:VB"Q$m_q7U[X5!@4Y!pe(UF.Z#YU"K[[2GA5N:a7f%B]N$$OPD_(t@MD3<s$]A"8K<1ff]MZsD(e1`'A0S?[/eK;"(.j9c<09/58p$5YbeP_LS:1'K5K\Is(9jT/;.3"NtA^"WG>r_UEa#*E=Y%f(@GAt<A[/^.K]qDLA0$a#Bdj>qfV@d\:0]ZN;B?JG;-C*0(-OcqnDQT?AS1Zf[Uk4s\>`08cJ?h:*,$Yp$#M'A^jq'DfmVA=QJqbo''r<&f:&`*+I6m/,`Lie:5lgK1S+e',SAUZ0>2LOB;_%H?/?Mt`MlQQ.5<q&Gb_i:e7#ITqAL[8nZ.?,^!+Ofp78J:rA'\`iPf0-ZH2L3k=aiGI[cQ.8QeZ_oW;+WRsNEPM5P@d]k2R&+2*pM9-8&IHDogZT@T6)#*./ZcO*J0TsD%/Q%C"ccToIk#qcn?'Mq#ef?@ZAs\6$"](_7Y>[ga>tPdD]&&a\8Al-Yn5B]QNaN!dkJ*<LIpUE/DE.mdb>!`Rr-;%WZ5V_FgbX$"AMbL&CSYRhS*_WA0qZGn8UYIil:!.[7XsdcNLYm!=@kfg\onU)FT^[(GmW6@lm7=2rGD3.FO2b]+b'l+VAo.]c/sHE%LKr;l@+A9,BP&p##seO-I"RUJ-d4]fhX'4B.LAI+,eclYrVadm#aeQF00\^MU3R4eUj-hr)jTX-F(SZ3AI@=k8bkn"]>&.(Ce"fT\50#OAk`RedN!JqpGEaG)Dr@a*<]3`.#k/56P;lZoeQqt%olh:,_O"37pZX[B$Af`>r/&DL@B\1tso-;2.frdR/[@Aql@D95JQP0+jc#FsrA!814#c!ON2<$bjejUOZ*9FO\=4k_[[oG1L)GVVE.:4)P'^r(JHkV5HAj+`Z2,AHjJmnhRLK$=<;=]V^EV-J@4XHc=>@tYL<<Gpkc`dpZ\m@$N\>d6 XEC.sm(lp0UAp;2 ,OZjbJmC4TWLA#5,Q4$[.[-nXI_/Mk=0RZR5Y*?`4,267N`Ja'a)9CA:p67de'Va4ZTs5*:_g>P<C^Gj`>(^gn<sm `-(4Y>8T;ELls#Y0qZn%%KZ?"4EYX8Q&>cl1]5` V/rMX1?PcbEN=+mf?_mOgpAEB;MQSk^\1(J])oAdGL,F'KB5iR'(:#i<&f[r-9Md\E(#2h%Cg^_:6ISQ+(Hk;fa7A(60^Mp2(Fl7`^283p."Y.bd3CMbK,b#/sXc6Oh:pKC;VS(UI<2T9A%t[*T8V'_AJ)m/P- #+1i#90\;(!)e<3j$pL2L"#oi^9L@)j,^>si;LXOB3p;tW1UHlHo)&GEQMN]_A^DN2=$;M3q7%\\=0V0?FGd269qJSih>/acd9njGn-Q-Y:n%>For#\7'o@Df0Be._`)j[#ah"PD:-+&k0,onnBgH;U.qN6/jVT(.U5Rp),hC7$_b]rT1<d3r%W"L8!M.3=`52(1D<lm#THjK#3Q&&WP E=Rbm?_K:X['$[*elP))Z-(CJ\^*s\UN9J:e=6'<7bmi;RSR3.M^4q, f-@"1hTG9N4UEoBWO` =q-4"Ahn?].lsqEF7ssC?kgR!H2\HDg(-%mD_p,:+M$SB7]ko hKq9@8#8S?A+pImPY-T](-HPG+Z?^JV1_!:P\3@[@!tP/[4O*M<A)^HAsNG(L^gSScOm0)2=;$8l3q<Cn]*?oWj V[P$sp_Cb`7*OUO0[A&7;1R&]^?alSdS'A+jMhc(cVX$dS=c7  $#9N(qV8Tm?fDsbsr+3WdRfW,A.%bSKE+AV%@eAIG* [3os5V'-1(BNj-Cq;5%*QVOGRV;nnV%Dls_*W[@AXs[AUbUWXVSrjTATH0UiTQ/;?(H>tP-X%`dSHZgI*1p8@eXK^DdYgWOt59-DED+56A))BU]mU:n.>E"-b;caM=YaZA=VB.k4EQU9qH@5R-K<!k6qT"V\j9SeiEY#"bBoA;HIUof: B%ACMn&fPsCpBhqa68)6>>eimVRI&,)q(F:AaE^4gGOjb4XtUpotYh7:DCk<`G,d8\WDn@pnDW=%j6"#PU[&?1*9R 1nINUf&LE5*tk]L=q(`+Pp'A^QFg"Ff,!UpgX?9_FhQN9 WGn%"6/TXB0i=@P.]qGlBhG-TV.Y,&/gU7AG2#t6+ZDM<Hf?r4/`#5<ZgIT!\ .Il3J7t3`6fI>hM9U]EaeVqRm'0@aA!_4XWM3-i=4X7I>*e#4)N@Am"8O)!YZT??m@,\CS3g$3!2_V)SoXh3ptCNXA'BS?a+Icp$S0Fp,+:rO%TP;KW'f2Lh3ap0ngKVc[JIMRsXf LT#n>6G39k9dj,4V89ccR<&bCnr$Jft*ALJ+Kd>,E<P3s:/#)VbqbsMO6`hT4J._f[g-t;"<Plq72]cA"JSAKKAAR,\.JWQ[a$(@Is[`f*rjasif` Z]1.U B<YfQQITJ8:-Ai\P>m4p940ItR[1Lg,A:(WA$d.Z)PrBJiTPn;kB>7(/=D[Wee5:T;n:2CfWM`"T#nW2X+_09\pr;KR0j]R;s)9F>k[oK;c&.'J<%,Atfb4a+8?#U%M7RpAT$7:!ir$YDY2$5lL,Gk>#JSbEA,ZgeQ[BEg""FFc.)5Gdm17UAV1@?E'No2ETDfp!(@>0=.Bf/o% lS(b[:Ji4-9RRiQD8IT.!bVtCSh\c\Rs7147GpTR*0g"o`D6 3;iHc\Qh8ojSW9*Tg'.RU@3]ai]O3Dsj-a@_0TZ_9Q?*<EcLfr>poA90%<S?Vqb!b9I'AFo6hH?Ic2WN-f,hV)KAUEUG HA8+cPIACA/\&^e<F.'MPD9h(tSIX9T.%Ps@#k9/<j^`CXnODO7/V/CFAmh-_cert^['gVC7C<U#dE!+q>g3mkH+->"sD,^TWp;W`-3pP??NI%QjO?lVqq3-h(.W Pm`/[`3F.'4.6/:@%b4lqtnL\86s8@QLZ\On14Op:jRkH0q52s..Pk,<0%gq"2%jdS>(RAVi:=7N?deR`1G"N9D 0`c] 30^+mBmYHW(,o<rC[\btn^G*1+rgqP0r&hVWVj_RotXB0l`a=o,\/k!?]\sDV0Y\.`rTL.!E4UkWbVV,V3V/oO?MA;4-ttr?$_26m23.e*-l`TTSX`IQFbWS2\0^Zpr0NbO fs/p?V80c)_!GKkp=rKAsInNm;Ajr(C/Y@CIAQ"$g*Q1gs#<JjIn@N?QA15Y]'+^L'hX$Bk*(.[nA[:jG?`Ah<S)Z,Fgh18cU'e?E]E$V@hIT1]Kg,%!1j"l %("<b>/:*g,VfP/?t`[:i<F@RRZGC3:4$ir*2%$o,g2A@+&NcZN8#OSIFiF%\Mt!EZ'4!e9;i(_'F7A:LaA&*GGgBLK"g\h4:(3',dCkR\"AZ5Oqt_m6n,N5N<!?gJOW[fZZ6c:iJrh\%ir"P2+7n4[sMqZ*EA^YHgTpA=ZsA!B1o7&5XqG\jSMU+i>1pd]g___+t6IH=JNUI>e8SCpa:g;OR:eECAj`6'8nlo@s53e\WB8j*DF4C) Jd`K#IPBX?#N2@#8OK*EjZT oMhTfLjt_TqAno*3`1T'.d/ R.kffa6E9i @=3k=F&h/D/n5Z,c tZ63f$=ma!%BOq]1%n's^k'ZmsGE4*:Q@7/JTY]iA&\KU1q<$bk9N9j06e]F&m\207TRX[4%d4g!<pb_heJo/Ln]Bf64Zoq\WhIRR3&,c>3,sU`cXAY9$de]E@Q!C%q8P281s_d7d(bpA.*`1in,f^pnIElntTT`1kJop*<<2^r?G5Y1dP5BBYQZ!btf3G#1oP'EY%N+'MU2q82,SQo6j,oU?.D9? rZIdf_AB(VUO!M*_7$,5QTTX@(AY7IcNcT>-U\r!$.rRF2!d$=MBkBQ*(A`Om5)LJ:. 1*c6YAI/f4o&%OCp33UWk ,#k15.:I!@]mT^-<;'_ANt)H0)!FSjpBV;7[;I1/D">_4.!p3V\CL=@sl<S=jk-Wf/jN$:fqip63UnU"d(9Ao-OY8_oX]C OY8_HdX"%8SXj?_/r$"<c:Z+4_-(A'%P JYq`\71]Uf9U>elia8UIF Ra]t^X=mFrQH.Z,kVnk`iFl?mB^;aL,6DA_HZ6A9(9n0sZ<!2/@j</'4+bH$/17)ADmR9e+Ogf5>T#d1GRR;tkP>a(q)[`!!Q9,OOd*Ua[>\5kXh,0Qa^j`Qn_Dc,&A\BF Z\]7M77#*e<X[tbhG&Zc\*j*O,ETQ<=$P_qL)ssU6k^mf])>'a>HGXk"=rbL4gF:E5cQFIS.0PWfh^/cMi4DZtk3;f;:]-QKmP##oD>`;KilN>6f&\?Yd-QmLoZs*7[A&UE1h*KCl02W)R#/c>>E!8TiNCY[NLh_aXo M_.7E9g9o]PCS`/)Vs4P9;fXR'3!XTO8*"LI37$RbVf8qYC]Dqp%BdUNX]RO;=OGd:\icQ)i )XP#,C3( 6_S9ksX7Ar[760bhT/R:r`Y-.\cr,Q1A9/38#YJe%L!rlC4mO;KCPMm2@p>C aQe(;9LdA.M .N\*A3,Xkk3p>HU,'f>J(m+&eRi`,.10dWkf#rJUAW!Mf$-6O""@g f1[Sm@@]d[nmR#hENkFb_J^QQBo@g+@2:e0Z2A:^^C5io&\?;+nC#RYC?-I*e[Pk3iA^\P]AB'q5)_ _C0h7r^mbr(VpO^>?0K(ATS5Rah[k j%@Z`[!Nb J3jAkf_S(\>jb-bYke>_@]4A#QW(M='_pm3FVqkBG1Yem83gB!E\XfR*!19aXN.P&@`V$b^+6PV/Ql1@Z(>`dhXh48@JClL=aFea=?dfo?V532QCAKYXbUlg8;_Ubm,!j+OSg?MJEMMX/M%[(\WdK :)ibP?LHj5)ai.pRQ"dt<=mA#E-`t7C5]DOVN!!mlLfC\\9&oj%AX]@1M"BB*bm\ >L.sAJpoI]m"IOMoRRmgD,Rh/k>_KT.m"8``%f`:2\bn1]!!B9Me5\@,?8]59]rrR>GeEJi$knYBNcJ7Ht4&TWEg-[end5AZi>8"WI!LEFTjp#e&jOIJtQh'%c^g14TmCH ^"`A1]Y*JU1JU>TU<#Lb4)lVVo1Lf%mJkS.g>VD1MTjo)-P&g^iL5YI8Li,n_!;3F3/e.\I<@;C3E"BIW:X\<%ULnr#W33Zq]KRYjGXCoU\mK!l.B7 7,/!_XK/jQ4qebJ/F9jh8IU.8hJ8V>]B$6_8NFc-bWtA`f.f,66;1o"QkD`1<# 2@HcgshmE,p&cm!Q_n'oWB'RlMl<9"DBtC;"D[P1:b^8gc!%-e(=?T2'_ZoiqWiA9&:57Y"PXrTU_'!UAfYA]H21M(lR57/e=AO'9SEUFG 5_^"^k>IhTkL<7Gq/gaFldm\F=.* (PA;n,QE/q@N9^$Vsedg+ar<k2=p?Yn$3?(eFU[m 8s<?M*!nd;J0%"ga21O<',U3GrDI1kJ#a8N-ZWA/iRTP_Z*Y/LseOL 3*D[*VD0nXSIE$]\5XYJg+(ne#MQCtZ":0f.ItlfdjR("0C+I0taUhc`J_)TmYNeQmLI_/Y1+ RI9^SJXr>;;&AK\V'!7>1#:_E??M\l",@4da:][-dr!I6.'lrarP!TA06=8*k-Am%osAr;G]9MdLjSj1>ThQ^Q.8JGN-YT;3=C*a9>#[B5NnablrMirPbjlD65!$Of:@[I25EWGM[X \nsIXF=qc`Z-\]^Vq2kSX=G;$5@LQ1>9_4*"4Vi"QmAkDm_ST*7;drHQ3if`J7ng5ne`%8aL4,f:Q5GS`LRcp7Z(4XVd^Iko=$]@V/ta'o -9hdlF@Tn]%86a p$R7Z.7bWcpgT,87=ZQHX:KN"6a^*0A/ibL"U%:E$&= )bjRo.+g`%JtkiVXN(o 52Q]K,XJ8JLf=<pleKW4i9AF f^r"=he!\rB$#,e.[o@OU(=sW@&fZ_gUE0grrg"g'QlF;AlTt72Z-8.[O-"n7Z9L0=L>T=$'B1;JI^5*Al'A$$!*PB/%b/5s[M=77C3BWb?Y\hb<f,/#aZo5 76G/NqTr0Y4N".E#0]j1nZrqUYd@Kf!Yf,/^(gf5a_4eaaMoZ9>$ceQ[pm+\:IL`Zc1MT3\a_o_T5603tl?dg?pr6&\8QkeVih6QD%-3,oT!$bc1[+] 2I"dh+QA1j<DM>rB>79Ud78"mnif$jMJ5qH>lr`ck 6[fmh?%2%9F8eCPJ/T7<0P%kP DFG!V4.N9IG"&-T%p,5PLA6PTA5`_6Ibc4lb9)#eLH("Q<AbHMkX+XiMH:`k[s eaAYjPD)Em(>=jOq),ZD$.'55&rl;`54' ]&%5W0HV[_/=WQs7b3>7[I $j;SDo&!c-=P<rOW?^dIr!aI#&e[b(&UNV_?NsZ?/<b$ 5(EHQb@S-M[&\"DHhoL3-_=@=UX'fiS5FXF:8!oK;+R\9NbB'=SQ`QIKrG9RG.oMXcrrtQ-AWbYr"I"GB50NN+sQ7S@E^TZ&RIL+^B4)+q2LQ&bDa//(DQ@Mg0+gRcZ1'Qh[Qq0N 5* B'rA!!NFdpJ'26Xo)5"<2dNRK5?R(FnD\o7iOrHk)i>@cQ].GPN3D7coM=Q!#SZP09*d,7:WjsF9[6<k!N-/?QAfK<&.1$<-dO30G6tV_h5T(45a"Hgbse"TXr:W1XDcnUp"f*R],61TVIHW+0L$YUS[h1A=c".(D:^eM@^\&UI30.aURP?P<Li.lo7r>72(17NmiVi)LGWON0BU\45;oaHcUOhhrT;T17Qcg6O@H(#4r`C65*<D1b)C(+d[Zfqqgj!aRoOtLHJ.7Y1fi0:Q1+:R:Q&5;IL_X.D;=-MrKQV>m0R4Z1WpeM:nEjHZ)sennKseA;)h@)a0f1@91A:r8Re_p[CJ9[o8f>^2kLA=3"kN4Kc0al_W+MeIk"MhrUT>X":0tOfo"U[A?h"AWa8Hd9Cn_>ULQY"fj>[:]EBAQB-9YW4\nbKj:aNm9(Dpbc[jiVb".Y,A^,F@".G=iF6"$G R0[;L547[.g(A+<TZ>I`+8!]d=$4IY< .b4K3&+0-H7eWgKL^34^bQ]*I:eC%qFtmrF11[jIQo-QPG>_XTraYIT#+T#bc]D,Y[nf7-l.d9JO%jq+=Zd91c]3/N%r-H=A)T;SMRde\KaV`lXS184CL.7LW4S+<^*2hA`PBFIUVXm3Ngfn;jCjt+VCOF(04T()pTfY*n]S^c0"!O5<Am+_b)*8*p[QDj:;/d+WeQYf^5b3^$CnK5MFBV'Q00JlLm_>d-6F/M9d.p+V1_AMJS>1(PWBZXG`hQCQ1]\7MS'im!Y$N\B%cJ<FqbtdAeO_IB4'L93HlPi[64thO$[e<'/Ci75^Zm)a*pU*!.JA #KGFL"P1K&b3E^ &Z8%((FRhS'g.SHL2CLGg<2C=`tjRO_bKolI%YlbF+:ekp54:pm5'e=:9nV0H"tSEd$$\2If[mbLfRM]GATD02`OG)KL,j=d[-!W+$.S$:"K@SVSZ i_TbXQb XrW+F8'Ph2@6GV=)%n5-q#1_$O+3q)gnp*h[SMVlJRI_@JQW_LV/oX;CEl>*("f^Qn-XHj)$ehjA?TmM!rLA7c9N**Oq> DK5Rm@[jes$PclOsE9EmDG:)5[0Ct`5_,Y/,/dbc\:ZG4K&0DbM.<]d`YWcPqbnQFYb]cC#\JL:^n\'s6A^GJVA*.8.k)Q##HI<lWWI:^9.cB:sKO,i?eIA<a488a2,;a"k 6brjjLXNb*24pC,5aoYKr*gN %6O)I"?IW(20FZWD1+1c4P-EnBWtqg6\X-*Id27"rLY5bU.q*sQCl2S':r0G#?bL?;9F*i-]/O]^$qS5H[SXpD?XFTK#0BM?\+-M)#YL 0&<8O!!lblA;r*`V[hEBRO%pb[#5;V=E,ZSa4D@lKdq^R2`>+&P*AldtSe%O=5V-U+`&SDbB8iKa4"'1MA7*>/BA&m=W%U5"U!$M]l+mm93_Bs.&%VqA9%>UL'?l1CH'\#5D';<D;V>FF?ia-pi2A$P=Eq+R[$\3c&%![H60R^2+/Dq8m6^rk.0`YeU.X@2LM_j-.ZN%An&EHGc4qO5/ZqXLU4OgKnr0AH8YDn*Q"o&YQhsEY'^KI&d@sCZqq%#UE?tNA,9_E8laO%Se\R8LW?HA:JA&qsFB2_HI]k?'4$-@-GrNisQ>$gaAALde9n?Qt+&L%1R)4)^Tar\fW(Z9f@%D,=K).sVO^W"WVP[X/-M.aN'.hQfO,N 7o"2`5Qfg3RLhkNjW#,qWaM@:\_=OGg]fSKrh=[\B=9C(t>DDr(geZF_l`,'&"*Ifp?N)cmT,6bOTRCr=A6,s]1sB3n,5PpRDC@m,,'jEo&:=@%Mdg:<^p=d:`8a<_D=bD`f/,([?%n2e\YK]"D*5Zc@\`3lnF5jLjKcG'A4RJI>J#(':t<rG9Z%&_FF[fj'q>LlO\$/L=/>\0^B&W+RG.iIhaJ8rJH5 sI9-$*o=@LKY0@c\8oVO9_OZK]eDqm]7!9";e9iTo0^XZb<DD2)MAAR#d=%sk*7JJTGMZOWK3PFa=e\=>% 8gIpesVHaLrgR?`B\!40b:@j'Io>8&$fKts7%c\>8WkhB$/@It$:oAlR40A2&b(4"/d5+/'-k  H4f=2UZi/QWjF QBX<"/ Cfa7:JNN&<E4a-`b=;^^G\'BTG8R)oCOc_@H,IIG<&3hMr'*(<a.&DhY5U(Qi&j[D]>qPeg<QN/o,!FJW@-0ZHG>5?cBiMK$l>D;mCQSJC? dYN:Q8rhGa4&9A>dtLGUkiYA<Bj=(/(h=O7_`E@'/e[RTZ:U-)fK55@JRo@4?M_]L*Z9^D(SZt>L(N5C-/,NE;^lq#%c-GWh[A+f;20+i*BZ:+9=BrO),&(L`N^s!@e:WDD#fWY8i_^dYReFT4? _"9hh>)k,oE["p-)2b_j:)o$TRU3_4X@Tf-E2`1$&i[Ar)*s'-AZdQU9V(^_mW0sT1V*/W[m75A(_4jOjRAc+\Y9i%fH7$4DoZNO3r#^=`s;6(1-Hf#\'@&R-TGYKTNG-gn&"(jWpA_,a2`tFkM=aAPAt7)Xh\]g9P&S*qiO=+b&*Wh`OL[(g3CU3!d@."+<%?DN#5^YXg,^b+%b=@sA'-i"TZc6l0flWAGJF#pL':>)`_(baUeiis+5q4"s!VaH+X4I@e_8>^OnTMMEaJ7Aa4SY42kjoR _d66kF6iHA%eK&s',ib[G:>2 70/dLeZJhlsLba%R+9f1/XosAdmAZWbC[\g#_c.cJ0VA6gAB:o(`2>O*$NO_E7^1Eh!in[dM!Y8r>j@dtFcqZ"la>,d]49+e!Tf_J&A[QUCr,c;?HO%ji7g_9J)$6kd)ai-P[^C?Wm)M^ <ppHKsrS$D$.?WGiUH&<NlZ6^t75]Y- L\Cd)hC2/(<Z& NNN59)=<WT;l_%`?QUB+8G='%^S/l]C[pgUhQ-<a("G@iTE>\K,RVU1)iZP9lmC2(Hod:#@$9cj6+-X3r)Sr9`97JWA::m;rl[9J*2XLE#F0U*IB<se$bK3j@5\#fX7I'THa`tV[<0=>$P]+\Fn>[%cWjdk._ <LQP?W^AdkdZh\QNb "-e=hp>tc1"2eWIR9#K9Y^5&%jZ$L,LB_K+19gB:AWdR!g%9?e>W/Emc26++H.\6F<':j#P9_kH_KGT88=4TmVGm[[N_)C5>;O3+>i=1F1UAE# \"J07pp!oq8d..g(((deH1[)^[,= ((s_9p*%(M_^7 l"rJT?l6n:iU*dgfaM r#e-_*+<c3jIh\_$A>ADo%N`>Abj9'"FoLZ#db$&7Y_U^?4*SS>dG;K#O's7lFWA=6qH'rC:0aeXFB<^<pa;6'CeAHj7W\A76A0aHJh%T(R pFQ[9U<3q[f]%Km1lpM[;[)DDp6LE'mBAnm9Z:t*&6Ej;X.->K(DV i%3)I*JAX3NNL jgeG7Q[XHVTa4\2OA@*5B[AIF26I]:,Bla4,I*ecIY.I9Z?8*)k`=#]88N;rHN\R_9414grVceT'LM[6IF<n Z=r>]qaa;:NHd@W!`EAX-D5Z?gU5?bZ_TLR!l<pFX72/gN^Q69<(tEnoP4DQAh5ga3.7gfqog]bBqj)pVg^QUVM'fU2[`I1nO1BZ!*9>lZkUaiB?iD8cjVZX9B^'(/OVNm0I_<e[SZ5jCM*FdXNgUb=(E46$a\T!U2kETI46J=tbA_l8"sJ\mClg*+]DRC;Wj#NT-Rjb*^I@MMareE/3<Pc77KE<krg]k]*mI+j3rYA2*k7kEc:9CnbZ3BHQJB\N0=o[>0&6NS0OD;;bK;',UX-GlB'gpj-n[fKaEn>sUb05NM^$HNR-<3V((RDpGKA-PdUA]s<)lV@r&7(n$A>M;D`0LM\ekE\Qjd.';qdO7 9KC6g`Y[N`.$1`raN?o;qR'r Vm@_'JF59($l21"`=A[Y%\(GAG\qIf5 )N'C%">WGA,Q>!-#RTW/?XRB:_n)^(RWBA]r^GF$U@A=oI''fAZ+RY;!EOV6E#sr<iH44G+hZ;`hR_Nj.CWM(Ns+_$a $-mrSr5nt;(0Y)fI)S4GEjX=`Y0n$B(q%%cb1 An;1nAi&-3\#Aa3jU!N<Vs846k^W6M<+bALW@3AA"`ZlQi26;LQ4cg`ChhUb"a4C4Mdm:#k4`A#nT 2SC0/( K:#A`pa5P"[(E*L#D[QH0SkNO#iaaC>`!4"^IqAU)[p$Us9q&"WLp:@Pe:Q?cLY(:Q\Hf"-V9?>akg=f$,Dcj&7AM5s-t3`N#Al<:"UVLG+c&,\k>ejl_qK?j6`&Or=Vd"%Np"b7q$8Od1:;*dfnp[^UJ[,6t)YsVkC@aU$>]3S/LKp<#40TGfNP*+8K*NUl!!]piG]O4A5#HQ@mE2<<REeK$Xri?jaA780/G^C7>rXNH"K[jE*5g^(5R9!Pi?L3N[:3AWOUkH@(%kZr7EMbnRn395W/B57o7d*pN`iHQ hWbkC$j%ge:%dT#6LcPK81jRcAd[%s_$c+q>8hO)l.bbY&l%>Z^c6i>\Cr.GY^eU/rq2C"mai_W?,@ JTTS*lHpL.DD.\BBEe<:*W1db#%+*,Ql6?+X=M_nb7%,%lh[Q,['nTHTgdT7j?*ls;GT;;"%7+bnB<s&sgK]pH`(-?$Do @%&&dVVN.*!%bn*2+-3#NJR[W8b-ocF8=EBpE3 TDZh9MN3ogXFA_*oII7D@UeRV5&)L<hT C+9df)-UCicr?SrG\pOq;cqWJ!oGB0o'ai*]Yb&2;6:ra^a^PJ$ 2 4A1&AHPYOlXR%H6oAgigg?&@dYl]i3id>>EK43GV(j"DQQs l<0A,/o (+G71o"@McZ%>0c'Uc.]PXt\>X@kjXWqP,,,V`^l*L&6(d\<*cc4L),GbBo.TmE6/@7OA^/^gA;!pPs`Wjk!RGG2\nG7aa>C\W@o64tKl7SMAX>k&L,0V19b.YK_:P[DGZEPLHX-/`*-n\AO'CjV+&Sr/!>)8r>&diAJN)I0aWj4m=&&&=Q^Wp#pU_-3Y13Q/g#"EQMpBS_1YP&9\ABL6Z6d)f#arHa!Hj?*X+W0:'WWOGV/1All"Qa"Xk\Oc UC><m!$Q QcI>\AqRtCVbD)X<+9pXrR&`"Q<.0-M.Q'c(XYRF0^%>#TN-V1g>Gik I@1.R.4@"HA;hWF@Kh+X4kt$8*&N`;m7UefMH)W6p]ap'J)fQ;)<`BCa@iqjGCDNlQ&-A@^+H)q0CEYsfBs^9+$b!A?ifH`4e`5YcN4WR$q?i;hOgQTJZ%^tZ^3bV>;+FGPDO;Vd^"l,TA/^&.UI-A]979L&'/4bQ&Y==om?pZAVf8;@A(B.FUY4Ao3rcKMJi8&V6pjTW9 1L-$M^@?Xo=Efmp,!#2B0 iT?%d\^Ze<?OLM$=4q,Jd9`,g$-2P%Dl4<\P<p:K8Eb"BP=f;\Pad(f-.<l47oN.`qNYt@'4b`m1TV3qR Q,a/)Aae<tjA(.XNGbL1Kc:V9_64fTk9J&*4pD9sC_AG<m9bAT)oq7D#)f\eq''K8F^iJi?l9674<-\&bVa)WqfHFgkpT'])k*';jIS! 3FJ?+YEJps;5DOl>ej-I+,Etdlo;GeXtq5Ei;N+QHKEa>:p70G6Ah0t$DC[:IgmKiSg7/3hl#Vp0B[;2dKL'SW%pG1PVQ>U_N)0^D[ALc/QTOaA])brkR5&Kk)K8WAUkhpSEj5nB]MLc#(T9Je#LOR$=gn>EdiskF\p `roU>)7C<G$L2gPH`rmc-AE$3=D]UZ@:UQ`q`=sO)18I9L!pDZ&nNoiOftb^1l(KBi9k#Ek`SmF&_d0(@t$Ybj^jnnXCVAOft4TD_s\%K_IcT'C","lpJjjtl7fGG1;J*@]BZUl54j6VFW=+QjTO[1ne*GO@RsX=j4F /^nFZWSPS=VE=RJ[?V$21hQYLS[c<1)jMEQSj3p;s)_?D_+s9I!jokC8[<TOg=b&N+S=[4\@r\%Q^BnB(M&$EA<dhbk;Xb!\14%X[>3Npbd+kW fo)kBat,qpW_YspA_A!fE/7g@YVTODlV?f+9LKMVI mW-7Ueks6oe4AF4]Qe6I6W!J8M+?IGr$&/r@EA,d4-hU$]bU-bAapk6/*_ 9k(1)<,P']K-_?KtcGg>rm/YDhjO!3lpL,t*D4j"Z63)kB1_A17LJ+B?#(?9*:q=X)VQc\pR,o:J7O"gRi#Dk18$\Mr!:"m*_dh9,8g0YIX`Zd0XjB!S+-Pft(n.?'kD%%`K>'",Oi<Ob'@=ppp(9^E:UL6cS(bc"p!:/6.%Fnkbo)gXSBA[WL7MsD^1 dCSt<8'0e&=p!<='NV*M@HI1qKX=C^&qR6_>rcg1L^\+iJE]!QEf$J5l&_nGWLGI8[B:k\qpJV1N3(/'/H<B^'A>RLb3G57Hfn25*[:*\E`^< ,<D "mmD;h>rr/oRh ##dl`7>i5"= K&;;2-8gsF"=(*FkCoFTd=_,7\^R]SKoRlkF8]sLMXG%Y[+im6_^`7fLgk;lC-)BpohMn0?p"6`ebR\'h"%U</1/.7K-Gt'l66?L>qBC:?<a?XG\7>A0-YHU%[^K.=pPMhB2K'q'oYgfnhsdH3:(LTqpV6;'q9pBsQR?X9^6W:F<5IQW#Sih2J=D"( A0CT9W_nKmV2,EH0$JWV*6D\s?!:8`4$)Q_366,!c(ga+Jd;lpk5gIE\k+&f]o"^m-R<TBOjEUfYIBEVMPRsg4Gr(ABa<UcV6^n-+<F%'R tL<YG=;T)D7FaVR^,#jEh^T9!=Ii$TXXst#8on/lmnnq)!"dZ@OtZ,M4rLbfW)t*aiO8D;)X+KT1 tY\j eX5lbP=?'`k<Z-9[eBi"cT" #%P1'&Kt2\E\/LBIX"\eQE8Mj@,9X[D*,9o;A'Lh#A/bHXI PdL?r8FcZAFXJP&iN%'g@Pa?!_%t_P6S'5V[H'TP9_[fFteS^oGc&bQl$H1?%4'S\o^dSABisI(]L7Z?<*1+YIZ*kcB[o2%og!N3BSI,UE)JGAlg;I5@E)G'AOS$Usn-BQ^\\kW-i?:6q%9".p^l2U-H@X78;WnF:dAcY`sO;9rhKlS^?Sp_dC:#H>)A(M#8%rj"NWKf"NcE$%l"!<OGEVKk[ftkdipA]>;&lkQ nB!cpgJ5hBh@Be7go+o8fd= ZelUGrT)o@.,EQ8Z>@=elER?'\DEN'iJrTYV*7&EQXk2kLI`CJDZ^,!dK!U1o1 N=*qq8[>t"sJn9 r].E0b*<rIe4""-Y:W1B%XbmC,n^S6Gb$9a@U+NK?k$3oJF=[-,@>>+S'Y`s;hpAZTDZHX+.DA6^0L;cA=B!12p#P=Nk8V@[7e7"9+YFsD[$F/TKo=>C8K<[,T$JZYs(k+cK?ZXgNtQ/H*9'h9@f%Ih>G%/U]V]VYXE_^o1h=a:lkC4Pb.L^eA4CXn>st4+jakA@NS4O#gD1V?5kOHNC he<B!b#CLtrP0/i !IjY>P&X6<>2UkP5J0Z&J?/[8ZElsB@[TMI^N3-85UZ /mUYZfSjGL]0@si:nj6;9;I)C20)BO?W;F$!G?<Y.:s%e5Ze3=7b8I#TbITfnK8nOrLs;*(GqG8P"HX(67Q&0I?8`DD;N9k<_(r0p#=P:FV^W,#& [H!tVq#g)rbj69M[;_aQiSN%r0.Q]$jAiIU7Eb\PEJK[(:CHjkg!U'>\?b #k`'>t"C-C'+YJ`@#Y 61KEb K?Z)5FsC>IIfH+RpL2>W"Q$JZg/2Bk;%Hs6(#a,_S%9qQ6_\;N_Dh"BGrOGN049+fbDSANG=*P"RoDQk91S'nQCIBeng42;,>&GA**j?edh,:>Aq\]5q)c[$E?('Wd-Z:TC5DS$BO PTUELG`jLS7_N>  bGiU 76%\QC)5FQSdDf\D>T#"^"9J] n/$aA^8n#t$a]<A]&ogN[l`U3P:r$1bTLFn`nJAP!ZD'ic_^6.8r ZYBmH0L[RC&890t]LcXM._c ld2+1ac3NW(nZp#&3AtsBeMFQn+'dd TAW"9.')G#W1>%-fW_j#%fH:JTF0=l3?oHUVZIpJoHlnM:ponE:,;">)l:Hnhg:@bUq's#DbK`L(,MU$,N+% r@@4W?cc[I,_)daC_?T"tSQd9^%`N__pZC:O[gWgdhG'b\^0ltg'O"koJB)J-V!iI3(1fjq7H;BrMlc0Vc"YKo(C/Wco2YTaU?s:<qL$?C905!*OIB,)kc;;\MhlhaP&bTV"o=7aN+$K%pTAT8rbZm#<h6f=O\*ioKh#_^FS?9keEe<[+N7l7]MYl4S\IaRfi_rYb$9s' 7ae%14p@=H)M@`5Wsf3_0Y.99]=1p'e2pC$l[?%-+)EkskqF@9]fj-eq8@,AG=[(/pLj;&2%b9iX=-9-J`s/f3taq*NMTi4P0QX/qCEDesdSTG*U[CC%3KfY%I48km+?$ bQIhReLjnkkKZ-P1bt:N<LCE!=WbbmR$a(P:hT[Fb$+V s9Ze>YE2rF<qqX5a_;M,fb/"PJs=0/iN<VVn$r.KP@A>qB81/df5\W3[#]'0IYYp/8qQ0[_*tN!3KeAI5-4`d'G=&Z)hpqPfLVJUG_>>>-AeHW&9Mmt,l1T^hPoML&N@T[[deLkgBa^pGoh3rE66BW"?%K))Nn2X*=5FA_6^bT2hnC7/H%cMkZ-&MV'0JFf#_HRNV* .@j6eU`&l2"W=R)_EE0h[-,="/m2='J2>KF[Nk['@K_,\%BHY4]P"<A\0k$Et=+=?/RX9rL"*K*q*-NP&pRrD^cGbFUm#@kTA&54^-+796 F0j]DaI/s[Ct9-1C5;?KTQZqaI*LKSB[OAA"@PY6Z5K(`-hLlRZ;5;X;jAOHhUr0@UY=erF$<JD'$NBpTn)25kF@^P+h=@E,K-gtF3r.(R;J:A[=Arfhq,=6d!p=?!b=lMokbLYc\iYOY6#,QB%Y;CVX+%h(7R9Al3+SJ*WNNBLQUhmIK&/?l34gci5GPUh#kF2nXB-P<,*&"O+ar(Fnhd3*A<P!?@!iAJ#fBVo;0RF#g+$N[#]=UO\T%K#r71-#l][9Hn/,%,e-;H++MA@L&[c3Aknh%j7o524%[N,Alt89rOQt``#S3G;Pf$#D"Q9FZlhM&NlA0>STZ@-Aea<&'BE;]t8No8RVf',M@3<Goiioi9QS;]Aph[M!n_YH""+jSSW#kWNL9AGsk';OjV4*'T*_=rfgP^6hobU]QaqlW9I=fjA%H2"fah./D3+'ccO+qXKLhY\!7 5FC';*aeMU;i<si"raA&0>4\/G<3jI`A(T0"@b,Fc0;,AfqSb0=o:a"I*5`'>ep4#4D&nQ6\=Lloe5Qn-ed&$4W.KN"!i03QP9DW+:smc2_$gO*T2MV6;';sd-06W:'ne-fpapE'j1,f2ieqam>mJVD0Km\24 _\ApdeB&@gq4%fJ3oq`.&tiR-(A bYiC([QPaT6].XVe'[Z-6j14_K3is p!1t_l^;?@SMJC;pJ=_6LaUer7ZpDO"@3R:lqT_(ac:bSd!EK*,sD^s8R0]as0lG17)r.(W%lA(q!b=J:E!rM8^dA1?Zk^ab^"c,Zd(@tD8 sM.[E96p.DKRG?Xl)oWB tD)(><V7M$Gc2l:Wj@^UY"jnW6j#)Yrnm)HYTQl\Eb2^$0 n_SYph,Wls_`UP`i)gT3FF(@FB2kIX@;aDOpI8Gr?hEPJTcn@2]7b0hk>REQCj(OlNi(gC]=!1ajYA0AHo[%2cpmW#=YIga?,f1E*W>9Vk(0DS[spBF,]+a8NWn2f3A)kOs$eG;5 *LGGH:3ZDK!B5BZ+bX][I,Jc47T7;#i2Re7tJK&]_N(e;qSY2l#.bU9mebC:8EE"U F+B.-o3GRnEtA%NM]7ICk(+h;KO`I&\LDE. B\VO+0T!-OiiOkh+.]RE3DDda0Mj:L^id\d#PdKc!Qt/W`:m-aH+8*gq\Zd)0HoGG(T:'8LH\Oj0`oJ(YU^_6ZKrjZ*t(S2d!8qMTUn 8Wi38sSCkKcZ"/_5n%fUZ!HRiaMYF'g^EXj93.-=(/oHe'!B,LGG9?cF[?X[WcE5\?=7% ]OQs6nJnRJ/':A6UGZGm7g/Ke%F[7p]Bs"J+>CCigJ(T%bZ"jnPIU@G$(++1S_@b5%mREh&2TbH5II@A,jS.[MH\1-b<"?Ak'6,(CjbRG94=qV%8 TJ6Z6&3(o?hYfKn95Wb=(=m8.IF?JS`Qh*R?@IEp,o7U-J4qZGjLnW aaf[VF(AD>YDU>0@ZreJ0L)(&F)-U$F@j5msJn)t6K-SGr:Td+9$PJ2j-s9EU6\:N'$=7BfT)bcHS)5AeDqbeVO6r@":i09:':jY_-2'ZY5['(PYtgge0LB(n/fK"i6?9]4)C9(;g= G;" AZlZW0t3bPYs^?t$OtdRVn:nV/m[@A"p.%9!p&AP@G&S^)g="qA>AVTb^=6T-HA<b[1/H0gPDPg'B.?A:,pqQhWUplAG?F6U"`3!'As@#Al\"W!1T7$2\PD]eM8:Ce&$=mbjn;#Bfj AJ3^BH?Q5i1@[omAolU/eBD"oAT09s_PRjt]g[%'Q$.p%lW`'g+l7Ae<;n-kc0G77fUln7;Y#YjEL#btB\5^nW9n 48 @a.#Y8/I)f;qn12Sd+]TgM1ktq8ZoPOk@/dOSq@<PLfFPi+FafSXchYLS`XJfj2e,Jc+(krLgg.M?bH,2S?/QSBg66$T)D>J@j+Tc;GU 3pDNba3iS3[$*FE<$UE(pF&@9a>)k&1MOK1MTY#1?df*dn2C>hH$;dK5>1b)=j"CNaV-atWE_"-\'\OPdRk;b1U^eIA4e=7k)U9rDASSEhs;H[*,Vef3PhO@&?,Ri,>BAqmEZ^tm._A#[@[9%jb!G#<EJnaYcX_[%On;EjoiX8O$4Ss_WZbc57 *ZmY"5gr8s"BTan,Y/t%f/8IT_-gAAcHdh#aWPNA`P>ft"Bn?:^0G4-Y`fMSLdelJrVb3:"KDAlPH#@m1!MX#.VDA6ZLIdnF(6Flqgd[GUtN:YDReU`>pUB<P"PV6VVWd)&1Q_ZajmA)+>BQlGhQbC:`b)A]:'AfM86]'K[A1G3[Yb"4oD.V=NhSl3JH)qA7TTW?)`2A[(.i=S0N0%!J1D:#";lcAWp>,#d+7MgM&[8%'>% P* kIrG4,JZh6ArHLiW<30`[U[`n0X":Z57 [N*HgZ$I7otWr54/Ok\NEQTXVZKt8D6,q.R3mp>&_IPAI(%?e!5?A/Qbe@ g5aGG(ni3aQ%8;=R7B4TgE=cNBq+FW\An6k@VSnE<(EC-dYOXi5P[Tii;s=l&'p1UFmJO[#pNbt8/q8Mq:I.Kl7<G+ATp>[5+g8)\XkA7=1"7GT.4kFYob70WpJIM/7`^?rOW"*C\'\[Ot%I@a\dc?'cjQPlh\h5R/M@DqMap%_<SEh2l<RBjZc[og?E2cJ3KjI_GL>lgJ\f!Fn(UQJHGTlr?>6mA,VAb3793AjHbXFg`E"d-kr59p,"q.g1FgFVB?%[V&V2T:?02JO!OEQ8?_GKU!:6^lAL7C;Mb@2b o_s\1j:e]df*LQ79TSjDhM;AOd/9Amf--]#c?4Z4DA*h&/?MH0(=W[H>U,j'AQ5=Z84qS_]io5sdC/Y!)Ro/#1-8eahG<=VGleBq$GtMgJ'iaA&!0>IGh<<beUlCkm;<l_n*Dqgl=]6g/%^DQR8]>Ar[[r(DdF1mRYX(:Ah^8=<_HA:&X:*+ra(p/_Dh_,i)B7 WFq+ZfD1/-rZ#rM-i\)%3a@Ud]n*+<H&>O;b0j3c7:&A,T=<273+Ib2EmD[`=N&`99S8??o&/@qoP?$"H#EL ER[h^aK(iFGP%TAeefT$Eib^ "eH`n!A5\Tl.DjW:'CC!8/rt;Xi`S_Cj$Z=H490!0#9:$A!52\G@WG =]X`K9CI4)gYNKW0]=OP;HJ/%pakp c>":0rPlQsSSUKaEQY2iD/7.]oCP"omV(OO5WnrAI[&&A`EL>R_/"r8.O/6cV Z$JsGlfKOZ:6t!G\[[;\Yjb42^6ROJ[TA=jbf9AG>t9_6pnNXioVqA=2<]-;[t7LX58k`<*K?\p8IQ0At;LEW0+H6+*fd3SaI'$<mmh5JkDm\`3-p2\Xo[?JbcO"Q8ZtmF4UY(A\'hD;>abi7rAfNh/,V!@M^H@_i&]O,^,hNt"(mg!7jji^R\ 5WC=]M[q_[Mb9.nl!"BTOBj&Zkp:0<kG4mm]&>X],&nJ$\]]S1?Ra^#V#X3](Q9qUlM2F<sTP^AAr+3@30*3lm:_'2#>qQefOt`oLUd=2`-ILq'kl';P-$m&dbNq4_Xmcam,pA6ZI^Z&eX3jLk'W0^hf('1^&b:oT=nOhOTQA!oh'^#R>P?3+L:XM@anPUHL8pEW+.d*,t`Q423Ea'3*,\8?[_7i8SQ,Z8-EeA(or+LtA^)r,Qdf!13HT>+l>jp'qK'!5\S+\1R[T(lAWG@*@WXWjiJ(-C,:$Q*g;ZAs$K+Hf3f,l'(.`2+Ltg=LlUj]A)h_.D4AVThb_:o"E,Ac[$r=`6CM WM85D/Sa&]RgDY7Q%1/8AP\-`Lla-5N?aXpkcrB7VV`E!E8ClT8gsmJb'3W`?C9rUF<AJ2d?P^P2,Nn@*_Q1]e5mKAA_r[WH#S/p#t$nf9A$YOS-qc2,qT[,8FnN7';lCZ(8Gd+p*V"Jt)$Q^JX q+O$+@fhHVdDal#5?h0&cI2<pmRW/g$/gePX)WObhkE[S@j>ac[X^gUQ9TDjZ"(jmU54^H*-E?/q?8cIS:dL0@ b]9#DoU)^p5b8X$*I51q^WsA'd%2O*N$0gEfr(ZTj5]CgAC2n@"p0tBEHN1mYX"?InEGR7A0T>VMD`$`9?cmc+SA!/^SHKc6PB@7-/P'NLQ)s%@ (7\Eh$-;DE*hDtr/PG[]J69FRXG2K(MJRMkOrO(Z`KnNC<)o[<;`1hDl#((g:W$CrPUn(FVC =a9A-p&SQ-.Z9I o(1,pIadRJHa3ZLTVh].bH;#MkK<-en/H^=(/"fsg&B*b<lI$;X8AHo]-HB&fP0Bt0MmD1,&Q1&9XU"? d^M.:^e&!t*9KTC++i)p=_=!)"`6Kb_T_F22tg,AW?8Q"E[DAK]%'(58-$+<?(.#__QLLP&+SVEmF@Jkft'"^L`O:a4TT3e!A6F)5g%>OAQE_X[??,*N/ ,7=',iAYKN OnML3[P^e;$Xq/Y-%i@[)P9cim"-8t<=^bh!srU3cB\&^^>O8IjQm5HNC/dnKsYf:Bj0dN_)i26qR\k8k@Q0]_tO[dGBL4Prgl'n@/>Uq32\"I/pFTG&X`QZDM/,O t]LC\nSP'mjQ:'NA=&ln^;D\nlQL&M;kAniTD](c28,8,18:6!M7n$&RVZce8TeHW#o\G^F%2_XM-/U5UZ9q4lg"St_'MSKisb"#e#NfZ,Ce(=nU] h/$U.Spq*hc+e[@1ZC^=2J\P3bp8$c58j3_O:0k6WC##3=jW!& .f!B,H^\e0S;adAUOo;6ekIP$>Rh[\-nN+,ph ]3C1"AntH(F?`s_SB6CLBsh7D@7 ]SAJd$j'.-aoYTsN)r:=>*Gf:U/! -03/6n&B$JBQ'70?@&G8eDUk:-tPpsa=-<W?3bf%d&Koh4A,@GN_<?4W^k`RGggM&'QM>lYS'G6,^t+WNDdb06]"EpeqtZ"fq=P'"pUgVY*r#D"JNmJXs1t$;P0;%$ORIhWYeAbL@ZSB&G'n4QD*L/nS/^GS_9?9>N]3fFnAGr!neR5=_cYH7$)Pcf<Vf[rh+C"(2A?.m,SQ+:A-I-BU-Kk6prA&+><'ls^\6#l5#gEl0o5l784M_U3.=W_qGAmQ*%%^^]6j$/S,O0"1e5/YmQMqj?<-TR!*0lOrtSkQA99kNQh.%r"dOm+eGSXYY8- )FeVXEH:P@Sa##kM\2&7EY$<s5^KhQmnQG,DrF^G,=/OC%2_K%0OL3=-eV/5>WsDC30'l"h>%Ar#"]CrI`Y2\8o#-\A+qnB[3Nqq!a+'Cab&_3WC@]2<t&.4h L<;A+'+s$<'rKGDI6KJZe]Yh^QZP4!4]NEjN/n9hb#kW#XXpnS2-dn=1gm/N`c6#02TWYWfT`/>?kr66f$mXoJHVQb1L;/"E/[_i"2A#O_@8!_onZ:KfIm25I;qhK"A3L@W2?$7>_J%UAKVto3lMX$-(b7s#nZRWJ C8^J.dqq^X+f;:nS.j'7',)boQ07P:be3Jja&_SjlSF/K<nWp'@7Z)=SVg/!4.7eTVUSKEJSNqCjY5=7sYiN6r"O1$L<O#M^$cd$0chZ.Z8CDp\qUP6q)9RpR&A,o,^jtm/N0n=9'pB6M1ao?B9\mC_6^i.ms ?+tqPJLB/XT6*(AYbq6*OOW"R+<:*A;"?$$!&::e&_Uc[%3.]iNY-B 4GU W\WB9*hW4>Cf]MlAj\q8MYh@X?E9PZEAhdOI9`bB0)DN3M[)i!`5iE&/6cP,K8fd$Z;6g0ZR&MA+m"ikA`$A2.0e5!2g==^N`#'j#rqt:\ _q.1dcbKhVo5QdUjl=<^Q%pF.J[KsmE/p<.0(?j=(@bU7 V`Q%*Q-\pdr%W@>etp(Y+?H+WbnN;JBNA)3Vh91?M<9/f7_j,B =E28rLFmb9C64o?NB1Tf]a4#GU:!(3o?;79.Ij^jkY+e7Q^4?[</gYgBriqr/`)CAY4'*/%9Q0HP#:ORK@s33FkJlCgb9<U?GTBL%jA8O=_5('CMLTA70&UYpMmT6`9!^%=) -[\Ap,eC?"[KcTVZo*^aj#8lV?csMNeXQOL@W<X(KW-78GS(-=r[2G@UH$_Kt0'4!L^;Kf\WjSATX-3>f:@sFiqGiP%`n/f*IHLa0CepA>VB3hJgZe32-'2hf$1) BHM#5PtgK<M4V-ZLLn6<?G;r*RP(7HA8MJWAr<g_.G=D8TO]UqHBsC/[eX"2;6oI N!0KiD&sD'n%a#VC:KS&_S^[m-Ni)F6n-`=,6;e\pi^cPFA,dY8ASA5$qK`dX/`1_[NcGQ<fmGR2X%\GL7%A kY.m<PYmWa-2t%el)X1pfFBI9Qa]MrLGA`)M,C\:G1X"_=._#D(p!q r'j=A;S?Rpii[4m?(kWsVD gTfDUoqdMRAS6LhENjl_;)]E?c8C:ijTNm.1GE'ia#X%5HI.)F^odh467(9]^j+aG7RqZMV)nHM" ogC)aZE*_T%< AcoZcCb^7eNZ5A4m!_SoA(.0-!cp^^X>/B'5D_/qY1=%*GQ40 `k-S D!DtVCL"a9kLRr;^Z\S5?4S4abC^_Ji.9=:kR\r=)D7H=.-1r.OZa.N"T7(U\snk_BLVsX%0AJ0_%V'jK_.e;o,A=ercfJTZRlB:js__+O%m9/`Z]`[CSU4%e<4T=F3<NHZ%MpF.Y.6g V*5/%!JNXEf=4H@B"ST9XQo4DQ?(4^B-g=e7?);3%=(ha)D$5+7WeN]Q@p,D;J9+#&l=>NGa83EIc^MZtk;J[Yt=&hJ'$PTA#8 F?B]XWF(CAKpLX_Iq5FWSe5._?it'%Bh7EAbZA"95NAo;_[WE/Z/0bGIP'FkIK*/Ie&la!C\nR&'>'c'n2C(t-ZcodJ" %s04ZBVLT1<F*q+D9L)qCWLC95Cn-AHn(W&Z&1<lAA3^faA Z7ae `\-$3LJ0464>OpehGq-lKmTD1(1"Ds^"^Oq(P?^66F9X\HT/&MUTcM 0OA;\<[A=d\TRPmia>:qdh@qi.IOBj]HO#"0.h%nSlXOGY[$mrSVp[Y0NICa8RL-.!ClD,90Hk^'k6a6cin/Zb!&je^@+[00bfcGFG(LY81#7tpAeR6Lb=qT_H("eb:YOiiI6hV*SF3:9iQ\d qs2h->dl6OT#PDQEbJX66i)]FtpBF -g/J^S\sl6n=G'Jr2:#B8)KM./9:S]Br[&7qh*'hl6L;"4f'[e8njR^#S@J6]4DAJST!XpW>?UcZp.d64.E#fAR#AQ"CFqY2BZc+AOK2VqA6I'YgjrfqW1rL?F[BD.fRm6+@2nsc3/liS%:$83NB]RUFI5I; M14H'Nik4^<'eaTB(=6L E*d$(CG@ >mUikAR:"3Pqd7$'<r\pUTi_76GD_e>'eK1^GU`>aMY*;?gnmc_E_1ct+b6LWJpR_AJG$b&?iCaD.R"S7VkB*<VpFcgg!`Lb-dCkgMC+iM`2Ope$l=55& Bq@niS9@ _2Ap!ok9A"(@#7]2DXWN_6Xr`$E7Kh!+"maYk>8&"h`YciIiHg_3%54DpD51IWl=V:5@t\EJ5I^8K3%8#@l85N#[C#<7]!*1MpRCS44&TfRhG_?BH 5;)CoIJsT&m9KBB;C<;WK$?9r(h$W0X5=W:_B+@W>O@dJL cU' fH,8;M<qL1>!O(08I?W8S [oN8c\,Cc&'bP.;Bh&(+$P*Xq,DmW)Tt t/(Q(EtlLC:fCY&XD0d[BZO0^ht[APo#Egl^c<\Z"FUY_A!K=j8?9#/N30Kc)n78ib8?b^7cU^(fT@q:%(W-k-FdA4Q\_8r9VB]%SP]?(:>DYF2H@);(A:!2$'QhpD:B40!K.BBlUk-,W5T;#QD7=Q;<jf!MrDGJ=K<n6<VY1Y.8tHj2Bbbg]Ht>k5,$:!,OF>XA/N#+ia]dUIF:!i"9tl:a]$e2=CE&KdWFBC0mA/(%d$qgD#5=e?R=S]\$M5jm)EJE4McR!Y`olVI#D%AAe[?*KXS,b":;275`hGb7QpHA5/'sqb,m@pXtWq#WC",L35mH[FD`P@mTP8-m=nQ5lOpVobKa##,I^iK=Wj8SN@^^sK(]2\<@W8oKs:<Ur8%E?i(4?H5(,5GiqX]A4:"rD*\cg!*$*(DN[2IaG:l7S+(K@%G%XGLW`5ld VRXkrEIJXk@,6RB4RBbrm%i9rYsE`]&^' $FpBbgjj8[a*F/,7*_Q0"3V"e2_&NW_Q2nM?E@(hjd1lm4O94'_6 IAJeXbp;m,!<rdWe1P>(J?H6I$k;(n]H1a*p@P:1+hdYQbTi.8>:j.H]q*N'cZ1a,a.IsC@c.rl"*q[s8K,kg:3PM?:t #s81l&,"5]]Q%N1H`D\WUS+AA!'\2;4@Xt*2b:JI2F@ERF@rem +O2.!&L#sAsZ[U]B\O$p^=;_WUPcp $-W/#_@jmh-kiq*5-LC*i>Q1)>7N;k[_jqJ!p^%sYC^*h)k tMUVh7E%P&TgZP\B_^1/SS](B=e7C3?%C=f$$?D+R-R2W)[ln`(Zn?\/k\;%j*+_;/AK9iJ <Oi%Z0 ?V6rHts7(MK<+ZPCpSA-t=1pS1!'YP)K5 jOt[G;.*.c.[[jGh03B<f0+^`f8rL oVGHDla<Cd^4rn8/VCQl.?m^AAoBY844K[nqc$JdKjAKfhFY<+n\sbEI%2b!n"h@,]*=G0Z6".b4qM%& \C5Lp\$t(nsNLq+*]^&M6=->Zb&Ic7UW&GU"b"*sU_@D 3Q"oHbX5;P3`UAAqF,keZ`8 "j6_fld7YUI94*YMRE*K99rnd$o78=?O>:Zh_ LpQ9F_L#^A3QCQ$Pmt8>N^W.)QBB#b/fefCTOO\/C[DbqdJN;iQc)_2K)i>tEN!t#Eo7EFcDQM*/Q$DVq73A>3q"?rs,DC^<@Xa*UNT)3eJ`p,0@eB-^MdL]-+AW?+k'TT"=*QA_6N#0QOFGW\J +CDa"d]!*[O+l[\"D)aLG*\Uqo /lpZS'`25':Se#*7@QG@>i1.@tN\l0)48QCp,Be"c7Vd8C!NOj7,,GA03+k\JAPm6'EkqMBeqlI`0o=jW2AD#Jr"eLF#K#DMXTA?)p\WG.+)@aT5$rEkal[sh#f)7D1:N<Wo2Kk\#&<^p+L1&rl<7:c[A/VTdH0H$OqA?CSCUB,$Ih%9r@$sScs!?q?k+r5p=<A\o0H*]5*+8S[?_2\5?_.-q0chiLg@j!bc-C5>@J.hLlbZ5gld*A%!]Nj+93+Mdh;e8oRR@(OQdp$:KHVG"_>S+"/0$AKK"iET>q4-g$g`'GQA#O`iA Qa AP+lgoob, QXf&Bm!5/(8N (/Ht#*%2/dPin7^G+<VL"?`6]PG0/[\I!$#;r7AI*Wo-4.d;g^4Z<UV9OA$+<6Gkiq%?OacGhT%F"\L0@eq>o0+$6<8RAVppX4`\eo>*RtAe7)'dO9B[GH:)cl<Aic(Z-4gZeOn1Bf]<GN>g 9epr`)8M;m#ftY:ZEMI_8UJdaqj)q ,h\piI:L:%#+*+7o.GkgkrmKBU"`WMJ8$XMWK=hU/AR ZC4IUaT'24[l.XLM,/.K,qtV(2cf:]Y#G0O_92(ALUY:.'q79aqZ4CV%P? VF8qc#^Ss3fGdSA>8SQdK?;MTW_UK"kj2,F#_OA/objAB^k_BZ%re/blK+3Rt lrAJ#ZeACaIA(jh \(Ne]R_`BNQ>b8A\P-"/ABZ[KA38!pWd00d"FSX/]S=CB=,)FO0QioNX76k`K:9,YD5HX(arVUq_-Y0c<oBV:]!(R-Uk%n;P[%:X>o*V)Z?h`C+Tt1o0e"@m7SVai']@hMG\*)P9M7S">c+bEkkCS>Hlot<dEmi4$KCat_n#)QhYAUUKX-ZU*4O;D=/4-OkOYdbVm)Ng S:Ia5MJ),E33_<^dHQ%j,t*#?M6SZNUT#CH<\a82m22`@NpdTH>(1[6)^ZVlAKE5i2o(s)rskb3MfU6lYlss3&96[M, .fSc`*OrF'.Y#MpkH/pde%<7m:LtYY&V)miFbqegR7Q ACrslZO^J@J*#V.H"r5m]5j.A.U7#82lN*]3'<!G]\lU7okDNnGeD3YRjJ1.YIi+W)nW:5-i--MgT9A]`p4b,.t_? ;_a>4mC2fQ]*n*`M>JZYCoAr6m[s7=V9Jfb3U3o77(9XYT;A!MY>ke"ni<TYVJ$6k.#. PMphNC_J*bi:DS"BTb[CZc92qjomnC;Xd*iHA3@F*C^Yp?Fa6>S2[0 r*ch2+bA U@j\VAZrA<6[4b08g*:-c&ke ?fU9+5$ bkkDB#9?FP_C5aTLiHaY%D7#empaDa4W%`KV$<"tD,H>GSLPNO'TEj./\m,jt6TWP:*hT'eP[<W)cT-K"#@2O@.C#dEaV!A\h\@(LU5iJLWjgk"!1inL]^]7%k;s3HGl$bs-Mk)q&ImPWb1\p7jGWH-6al08 67ZKC9`jDpABZ:F?nP-KfGjt@@\<m.HMP"(k7$2,3e+q,IaQR-Tm\*nqPkoSZ%64aR5s%Q7!3c/7[5`]pq;!q17Hl7@tJi-VeHT5XatX-9CAIf\Do#rG#UpnNVrQp#.=LA!#W6N=?RIB\fL6,b1O19VkE0_U.SI.OI*:m=De4TA9"jm^`3-6hs8&XPK/#WN*\T/s5_l#A7b18^Z`?@r`kP=VJAG< ;7!O>?V]-Sr_AbFZhABkt1n?t0*Es"WQI1i',F#/=?Cd<.?!LhStaQbW0,1DS"<A:Y]5rIq'R<[j<!tYP8^mf=,n[J"]>V<@dCam7\A-[<&3qo:RSSHB8\8qVEAlG8n#$fbnV$5RHEtbD<lq I1CBc)ifh@CpL#$[$AVq%7I"YfVV+^K:it@'t@^5PhD5lq`A<1T61d_i)2TgJb0RCE2BEZqKOn:oB3 Z6[HSY/ b(eA/nt.W^Om<-r/h`Xf^dL<SLaoJ%tK^WLVFCjAO0oU0J]]!Y6sr%]A00)e.9kB*Yj<6 bZI#G&eR#Vi]*2T#TM%VHj8+qt\f9AbH_7s,e[=Tp<iRPNO-B7*iG#U`jpj;,PSO<(.Qs.t+a8X,1hTI5%r?MrpZp#g+j70.j@Tlc1$1nP0&LEYlbCUP/NIW:PG;M<fP&B_rL0,h*S.Z=)0D:!!a(RMQ4'6W%E6E3T1'n@ /XF8L#NI0 AFK(g=AQrfq^?2BCV@O`OG)#lh9+;` `9+"7I2koGTpm`iaL=k!A9tDY"d8WsCPDdpNgU<9P+OFS1cgZH*:2q6[3( -[\HMJX$X*W0g::t@A/$-KGm-rc7=q)-sOVgn[^AWp(r0<C.Oh"iRpn5,kGV*_n9Y\hoAokJ>J-6QA%J,OQ47n@#mO1'2Xt)>_^oc<S!2ZnV6"%$PHL7PM)"]'Ng_5UHp PV,qf N(D1E)RW%Ilacc,MGe:b?aZp9^(mdb>foAT>Q`>GkdZ$<J!gShtU\>$aM-Y"6ac<j(hL[_\c((h@%5nT]V^,]M*JAblrMZF^3^S#''^s![ehKE,E?]mY4+ql<F(iFD#G,6XdK.1ZM%j(1hns<R!%".-XqgS<Kf%Boq;^Gg&d@sq` 5i_o`;LQB82D+VEn=1\,(, t<1I1@W`$a$"Gd08n).hU)2jB<!Mj6?.NZ7^a/TXR$jBM:>opBLJI!N`qA96bBoap9c5FR&(T;as,B9.D)"6n6A#-Ikf8YJML?$N?eT@_]@Y!R*B!J&`0!P#IW6I`eUO>qm-NA/W#hJjN!M\>=%iXX)Ik6;G`Rl.BJF7b4+Sd7;q-Etb0Smtp`7/02B^]@7>GHJn9XdWE1LL'bon0j)f7=9-I9'5gi)-RHhV?Y+gWL .W2*XAT-qg6VW,)3>(86YA\cIc6%s(/M8FM`/3>#ak<Ua4C#WL+-6bfKIl#0jl`,+I(=Q7B1=^rF@(_q-n$P`Z.a3E'?c X7WNH?I\&f2ip/bK,9XN=W;T(N2j<QVCHfO(4n2:-[ht! U7p1aVBs8e42:djpo0;b-?*DZCl1E7i5p^pfK8h"lW?9VJ&+^c`MRtGYZb5GN*aJ?I`6;9!ni+?EW6cLM[t2!=P.Jel)#;_)5N5ThTGQ6I?a;$H>aIC>"I__#?ls`7PJ*Q@RZK/.-%%9to<BXI!ADAdKFqc&0AE1GX!^PI5EYG`ZG4;E+[!2=&JWhc!l]<&hpZ%QL69.p8Wj<M>T/m/V'"YQaV1kf-Pg+$;\*grK1KD2aQM1tLp`T -V+qXm%=$@/%'k(!f?'HY"9")?KZ]<13,lPL A.CXOJN_h5$m`%a[S)fi,2j"C(aAsK#?db:m2EG\ Bhq>Yn:VVQB`VMLIK'P&n$- Scm&j=ilONY6qSNS?@j)'s,(K;K%\1m\A$Y'GHCPG_sJ U?+S`cXCrDAM0_jq3.q#R/FMf2JekA0bWY%UPQF>E3g&TmJZPY1 8bj\Gj^`q@#!DMA+`1rhm:]n!D!V#.\kA485=ACZNRP]m"]fhcJA.@&14C25=Iq]FdO7+XWe+ )S*qre%GN[ 9=$t8,g! $l.1$[MO+FUXqq8o$[dpAA()4[8^> 5p-9i]L(Y=g:M%.EM:nCF6[O&"B4;MQQq;\E@t'/1,NZ>:iXc6 *QXIbbU<Oc+V-,O(E9]%g \kH *AS5Htsg<M'pX3A%\&H%r\=:?Bn*[iFAY6Y&,sd,t+EVJVR\4AfB$0c@X,N]B?<d3^sZ=rLA/HEhJ8!sM4;Rb9AYGtfRk^'R<,<Wb)QW)K!nS,+Ie'VhJ@N9$.0B>MA"[jV`iAVA4i%HC<i*. &qa&MQ5;GiAkM[Vg\]`eA'Uks_7mFc$T6/(-Ma_8X:p1S+L@!91Yk,MOm@l,k(HdtUM<XS.BI(/+/^7)gh^7f3>StaApU?fs(_(&c-`?C6W(TD:QAABR;-=p1VhDKoQC=Gj_DQg@j?;_"Vm,8Bk#OZG8sCYkii2AHa7'-Eet/>Z`(hFCN ]Sa';LE>#qn5:!a#-WGAQt!r'BAFI:B'r>6nqn<E?rk!0-/@>gBVHlNK5Zf>9VQ9o\*Xi(1t4lJT  p#YQ]<TG,Ci*=SF,A,qSR?S.Ki`]W"RAMPeWBj0Bn>1c37h`mP-8J ?qRg['1UY2!KB./E,`BP#Ca-RNbR5+#o,npPUNdCp]@0Yk\D1*X/+cog&LS9?O12P-:.9gk`)K#=SWI0]RV\H<r#VC#F/=5+(i?"@mIT)a2>i]-b\^N&F;tUQWBTY3"[94O!8mc`?__6,[ATkf-X"-h?Qs1hs\1&AP:d9R\!Q]Ul&r-NgC;&D'_ gdX%j hX[hk:p6khM#7'8s'/AfS1.;FFji7):shg-1?LcP\*0cVT^/g.4WU45eMOms'FX8+ihJ!\ip/>)Frb$pXtIYY;U.]q`XC8'->lm2?0l/_9d$1R#Q "MCPLgc9t M/hASnmMmK[nMXJ5-Usj5^I?Ut$1:O@FYsRm*V<@2W8EhOA,g_Cto"2b#p_"m[_^`Yr%O?g);KE,/C4+\;drM)$*$UZ)7_.:DCA+k2eAk!sB5[I@5m$Or_+:#^`M#L%M<N-pt<Pb12Fg9[i/pFF<YP+R!(P(2^.JsoUF;5fOb),s^X*j.J*RXD0ei*5&U:tW+DQEP7RE^d>lj&P$XtBA1Z>4S[rf) o;'?;E>+$k38#JNNke[RO*!XBKMq$RaMB%a#]FgtKLWndl3d"OF;/OTY'2a56Q.TpOnBT'c#52Po"N jpRV YaZd6\4/R0E/ZY8@G*epS7ja&_M4W&OI=UjQFmR:]kma"f_3CrNdepp6O_-k&+Vg4-A)H/d,@ZZ;41X]XB`;3))Af12R8d%nqj"9g"%XJiKUWM3'l`:-9<(cc8/OAUK,G[f^iOMoI>t.At&n[(+Q0@pq; l4ket*a10XhApT`(0H@Mtp:UP=5M<$SJFm%r!/J+2h4?:e36P[]54Ajm^#+*R*=eW19S[$&(psd<P*&C`"/$QTi$qhqjKf@,(6sQLg@)OhNOmMU\^q+nfZhESb*&7(B1bOMtI`AgYXJ$[>MZqX.P5:'G5'@\-&NEk+(Ptk/t;b7O"'H<+Mg4*Kh7(<MTi_Gb<A6TL,=NC E"s]eEnolA0-cKcFiqH^\K/pDn^UM[`$;7)X7-=eWXa&l$<5_dI@(,UZ&,-/Q2K+ObSYS(&4C<p]/f2NBa H>c!nZNQ=;i_)3iE:gDgIl;a^f/l/Z!7j$;p16Z4rqp5]8<K6T`5PN:>8j[[>1\?psffh;Yq6DBt7joW#+T0E$b:i]L?&"LR7`(N1cS^a57>O-!LOG^M'bH3VqY];-:dCetc4UIM`ciab,_Ek18dYU"g';'"HKbF ;>fLTPi7@sQ-&er``/-X5C/A.G%q:e/I(I]dWTV/BAj\HjVtZ>aO,gi#o=(;1D%tds3@\T;ZDC^qLV:Wl[N9i'=VWD!j9P0hBZmE>1dDqS][[ABO)H(%E:'R][551":,UD$*U^`lU&9WD=@eD!]R74X#qo']*FEO3tkId2eEb"=cea?@04l ME%QZ7oji'B/l`r+.F>9@/c@dh:W]E9T?e2S<Yo,Gp%U$2CM=.>?W"i>l/F;f9jF9/do%]S1-9Y:sn[8B.!ss^bHB7[9>TQt_n7W]2f&IK3KZBLAR5M`-:SQG=Nm!^2O=oXjQmN**Bbg82=,?%1 ZRb;4:-tt1RM5T`%)5X6Yd'3`0c"UT$-$$ ipE;cs9ng;KA&- 2 p\0#/YI/D2S=p7qF%W8kD9.T&E>4[d_;s=(*H>p,ReVW<d[h#+*4&'<fdN/HdeK`ji'?#D@jRI*dG;m&"=]3H&EJ;*^i O9:s!CO_*!IaZ]n$7ZB_1jI(s!oEacM2KkIj:oP.Ben]O8Gan,JDmr"c;<p-^0phslSp"8lFX%XOrYN\1>nLW-U)X!.A.pI'=Zf*SapAW5/$+fak%QqgRL`_U"CA!@LAAfjE-Cj>A,`<?m+,,W3XOVQr[kTQHY>@1$PE:<hYtW[p$`M#r*Oe2U1p"h 3j;Sp9"p3gY3D-Nr$GEk('G5_Rf,V>LSf!'FjLjR;;g%j?P0?LiC!fU[AY>TQnp6[*!Pf60],b_%DI/%`CqMgDp[?3;P`M#8U2BRAm_^PQ_8,cFB!O8*ng9o#^::F^AU_JTUH(IiNs3]a9V;01;<7Bf-WaN`)F^"Be0RQ7<nM8f`WeW7OlK9,LFD?A)jr7Ji_G_R5DCbgAP(JHf[c>LX)oAFlTL9krLkY`V;_8qOj>k#1;Qg=@sNr)I&/gAgX lVbhF.FCEGo2ChEgGH0:&@TBik&Tb7[``d7T>L7-_%:Xf2n.ldtlj>@Bd= j&N[<HNAi1gI]OgCY!+MblZ_mI&98MP-E'0ToVf(NZ[2m+.<SN[LUsQS8bXcA;8%TA\I,:`k,&1LVA6dTCE<AVesCQp`dF8$ ) 7q5(`K>s[R@5cQA*o^WAB:%A=kbN?pS14eFM#Y3Ls[b](spXdn>7[1"(8XY91\g"8jdkQ_)P[FE`O9A?,!ZGs&l8>%1%6EMTA_qEqsEZcH!ic:.=[IP^7/q0"JX<n-A5nZdH0gr(`sTAQli!se0CJ,EY/,0=3a5q<PKSoe8Nl%HfarS(8LJC9@RgcAf];$7l0jD<Vn#VNH?tE"[_B =7S9e-0 Wc\#MJi,8Ose^;i<EQ`-qA>Id2 8Hs+2AtK5l5ZW^%h8([?A38LIPT`PAshLUs,''dC.6i0j^l.'U%9Z!"YEal*$6s2(N$nM21&T')KNc];JP,K1AZ&HgQ5g0i<H*&1UYcE2%M(".phj%9E3sgKQj'A0lU5i1@4>;@Alof@02jOWXa(mdOktRImheaBTF"+_G9S$6RSn';FoDmm?QeSKHkA7.DfA]b.Fi1k<YM&OA/(pOL3AK&<natm2/qhjT@D""tnT!+S&^eI#74tY_6ASAaIN-fMR[e#7SP1icW5_/MmKZ'2?.S4U&'EmM^qn5K;&+tA:SX.m6K(Ts6jEn4[YNB7,IN44'tVRH4ATc0/cUch;:4RIIZ"t$jRq7"[@mSkpqC,^E0pDC^8`%Phc6@)<+C`dVtPA,j*Kf\QeY"(BYU`%^]5"LpL].bZ5j2&gT_Tp2MB.q%aV$PRl5eH9eon9S[3%+E,,o.Y:,g1C oQe_.tqJH:T,"VL6=WTKB0 \)C>1LBMXk'>K&Al..qA1daLmIQAgD =bl(WW rKQ^kg!0_HL08,_&coL3"L)8Zp(cm;K#J5-)#V*._78W_AR($ZKHP4-:fPm0@/k1!8^[BXSoQD!o:Yrn2"2T^"Jb9s=UDLX5W@Nr@'SmXd'1c'VspfP#7b4@btdUBJN3!^Ye@n\;)Sf#HeATK9mrVQ;='!-::"IJk[^1n2Akm>Gi,e,aIAZ783dI&Ns93`,i)Ml@%l^Z J-sqj"b*a$$9Wj?h)>a6(0a4@^a`NoF>EA2Z"%6<RnnkG*bZpe^^Kmon;e?a9sWl$O1_)AKS0t_c=Ye$TYTM8HHQD<&O>O@'9%.2PaXIDk-MB^h`RTrFG"Ki-]4k,[2kB63/da"r,g)*cH;HC-daTZ_,Bk] W:? ?`,e2`=TCLJ@knRUkoM*i`_Ah9PKTTIatn#:pp0;T_kfn+$c?Mq\S$_^Yj/?fOK^&Q$-94\0iF%'8D/C*3@@Xf<aQ?:f \JKB8lb(1mk/tCA$UK@mZiIL%OMg[6fD5UTM\3KXYTI3hV+%[AheA=3DP j-)h7qo7 0.P;\)p1DE95)r"`@M\&/^lS<Q"NEn>cGZ;K]E*)T%llg]b^SLSt Vrdt4)Q>?k0SQQ6:Xeg@pm0]1>,TnkC s&LKP5n:EHp2")g='d@s)2;-Y(Ud!A-'AE4R dVZL>MT)q4<'9Ymfs*9?Q`d)b2H]Om:]r+Kn`gt"_>:)t7!GA;&6'h'-.\lr'erd(b?#9?9Yk?T%;AXE?=09Y[DSUh4)8HltINi0J#b]Bdt"k,Fb ]NBR2/8_AtKDN06M,(Q*0IVE:pG[%)2l@A`(R$%8frtGF^i!6c*[)*Mc%?+6q[0@Zq=V^]`#/U&BT_'6FD*mS,AHh["]`N(QVo'7Z-f,1_^s&)nG!,A4j53m`k,%Yl0i]A2S<lVjH_)@P*l4Drso-5,1HPtCnP7L<:1-\M>6"DHDUN_,kR.66#dN];A$\_ggOGpVsS"p9]cN)rL#C511GK*j9H(K(0dqSJ]Gdb5A!Gmn+hFB2]jA>'@8iscCUTqIJ@^Sk-GT'pR9<P_Wql2^,(O&'An3Qid<k,/PQA@ 2nUm9,%OOK=?TT 6Ei4 KsKVI[H4t\0 cs+IqfMO)U/PAJc<A>Ahi-0VS=^@dbe%;!On(OYba(j[*dJ>5b16&<;>3DZ2G L0,]6V$0)Q(fK9o6g&439WHT?C/W&Mkc&&&7g2V/Kq"_LqJeGEJA,U%Z`^$eT reZ34p^FaPAKF>]3RJZ_,)>=r\E1 I-K)$b+ -@[&ZT,mc0b;C4A@T3,]Q97>AC% ZHN b"f8D *a(! YCXb+^Q8j4V6+*:<]j+De"ZeR(fL(/@Njn5'&<Um%&YssN+Z@_\K:cBZoh%.pLKn0Ho>JG`?@f.$AL%Ht-:iLUCa*hl17k([ZY\MB kDRh#JS]J.jt@S?LBh0SVG`AN.?!gqAH,4DjnOmK&iG#[P2X"H!fb(35A[cr$HLcY`cp^Sd_7N[]@o2i9,N9Z7:STafZ@E>,"oXL>W""!IsW`n'9%>O9 .]!-O``>qCK02AHnPOA</-Ql`?=`e>YDK:f][ZX;^E.mF-#JpSNM45q;7Npc;JsgQVtD@dnT9n,SN4Z_8V3ML .Bd1brK:0]9[-'!?gqOl^$g9#<IWS_Ftih4UP1S:e3D`&2*KVC=ae#m5qe>he@F/#0AFi44-GFOmX;1Y:ot=40rm%G)rZAp*;A#$]bXcR)FL.ot!/ HGcOY6eboK>T;c`Q@YZ2)E95k0(Q]Qk2mG!lA;3=?"f+s>Z9gOJe:`%EA]IsP^bL%a0'Qns/V/oqN*X\A*SWV1 7H.;U)V,f?6l26J)'r9%S8DHKYBSA'6>d#Y5bHErPHIH)h ; dcmLG9=WNP^dV2+N;./c>/.'Yg,G!Z ^"c6S3H+AJWf =i\^<knMeM?pB_D;qdh5fq^[ ?H-5Rk[OE6XOZJIFDW_bsc$d+(fGb&32K],qn3L,WIrs?9=/*tX*A8)t @$(OZ1=.g'PoJ4$h!jLi$8qjgG&TO*:TJn2(IqcWXjaY@LYbT*Bi#s&.\$^XgkpdF+o3<N%X+6T!WEn.s_Hnb_bo_>@CX$IFJnC(,AkAGfY;jttXd;0K+,#j 74DomGDbk'5OeaYs;*0R0b]$N4L+#f"s?8$`t9;OG%Ya@kQfAANhdLr=qRH:2e"T)/b`Bjg(gD( 6Pc+^[&VdH@`B>"qJ8NAa]8A@t%qd>[l]RHQ]pZp2\In6]5?]l%j`&A)5r2IQM:;Y9rN+PP*lL`ZCP_@tq:r%T?B_$39l r\hehLm38iF,_7?jQ"=.\Hs^+nEs0Jp3[d.3mjc1]OH#`oM#1ikiAL`]8p&>Y>.AKBB4KGA2r%(Z0K1\QW7!X- =.BLhN=d3as/*B^#MY7W>5hH,55H1,tMY9]Cs?H4/6da 2JSJa/t.(Ms+LPPirD0MXP0!NF6 =`!+`A`RfU,&d3Q+lK`,e)6$IcpA]r0mMfncKc[1WetLAXiV7]U0AHB3/"nBr'kYZU_/3:joQ-*(OE.2,@L`K cM;WT3sF>(s3=-i`o!-XdtHROf@RQK</!?qD&n$-jMR,\lSTen a]8`GT_jX!+Ed+Dol3L=!A^&ef',Z]pm1`t'<5J!0UP0BehNE_0Xi@qjBF$#on10Z2cW?JW]EC b?QZVHjIbs>dIh<+\b,GY!d$r.8ho5%KDtFok?`?bP6:T+D?(qj_=htP0r<Do$ Zk8%:.!0QRS9c%co@b$"\dEYhQms7,>*[6B'WEt"m',f^<\`noMW!_e!c3Gq")i?spm/#Yp BAQ2jmc9G "]FA`L@8h<aRV/se"2iUcA<?e).bMNmnQQUR9?bAc5>2aSZ9X!Ym`fKQg%ViTALaF&-3%q/BE(s/%`A7q_lf8DJrfgT,'o_(dKBR7j=o'G2Y6"O`<-OCWTGRV/=f8HPB:d_/tg)@'" DjV?mI%[4fE^MtHE8eeH"h2pS./3#@Rt0%T"-"X'aLPgmk&1WC7^$e,Sq%Zm;%.+=c)2MMg2@k1JfBNFJO20-$D=@abC+kKf5`\-g9L:tl<SI"+ZGIH$\D_`2%jb=\G9#L@"LtTjSP5%t>l4(mq\6X9jH(?dUVK#t>9J]H0?EtAO&:BW_pV(mCX1qoP1&ArT[oU_NWphc14NNs60UO9]gbTH` >n!IH%IO*(FaeHm-ePb(>t<i1$,V*-/DnjWTK50\H\g.:ZCnLI4e[j8&AOd$2N:W(ejK5^9#q3EF8@5Yr#*jIV/T=#n*iDS2at#GX]hrpNYi+d RpXW30Z%":PKTG,4%Oe"tp1(LmY#>'beip%>6(FHP-)+JGN`C>D4ffmfcYsWcmJXBpOVON4``0Q SHQG?@!cW/hoZ ']MH'^0T!5"(i)h]Y\(9FTfJV:4Q&ac[Z*f:,@(pL'T@0:ooO73t*S.S R?@3gc+=bcCM%M[$P:K<;o$J='rX9Sr h(fI^<TnMj6)h +1ph7O_jnp?sn!5OoLBUT(f`ICL0jFGm7LOhSRecX[UU?B3Zjl'K$?,V2Mn?2`[X!4n6Z/1st^F*\G,Y5:SNHYpGcJA(#'RB_$gW5gV-\c2F$I4P/+< [$j=j1o=r#'i#!RgPKn<W>fR\'E/#][^@Y$OZBe;-88NUnS._L,N\$5cs atk#T3A$ffIU;''(A$%rrsBGD;)f.Ar(>3/\BQr\Tp@LX^_71-\)@q"5U+dG\m45Z[RWI,RY]=UE=nSh4\4*(F4K?&Y-XSFAP-irK]<">lYQ-?o.j_N5>#L:^aaA?%Vn8VQ3'@m*sF#2Cr^CNV!f"S_WMCICaMih:_?p]%MLTPB6C3o^&L!<13?gm_qY)o9;2hGRSJoD;Dt-#Yn#e;<1=OL7LD74Srmp5&UAq(t2;"bQ/\5n.@$kZ5VR*<d\hC3%kp^M]JHpV3Q@,QCs$Wn!bo%d&H@!eY\e%pIlAi+J$tPeo4"M5hT/:NVP @nkMY9n  E[Nl^"p6P*R&VU&AOtBA66ohb4\f(9jj\fI0MUm? i%\ZJ-$Ea"W0X,lm>(Pd -Uq%T`9j[S4J@*g14fA-LLted[D.m7f?"#0olA3Q8%m4KIoI("&Ks,.d@5.m%7S.D*M"XSC<iUQRKUHa%e%8LWNS#]I6]](9""8pJL'd'ba\l%9Rcq%n^hZ6'=pF7^rYsoBnGcg_T+MFV<k0-h'*YjT[-#DfD/L`6g<e#;Y,9mb>qp<4M^M?<`Dt9NU^!=UXV*Y7'P=jA.:-^ _hP5oYKAgO/-VA];+43=cTaOg"(G`@$6M-J*C2.jPo9)Z%IOq7K'5",U#XK(WTc:D*s0oSK%(pEl.Do3Qof+P9A"Gs &o-20FR_;G3Ab:KV!q>'JBX,2'^>->L`,,8odNI"\<&PEk%E99kZB'#\R:.bgbgUj5**>=NE ok7F-:0.&DXk1Y_h(3SI4ki"GTe@%(rc=t4>jk#o!@rTC97+bJtVnc^[*tVpW*6NIZC* ;kAf*))ghWh+T`47Y^6h?s<P*0ds(h*"8Cd$ ()W&_95S)U9>t\MZHTgTBZ01;3;TQIMbjC\PA]r0$D8Oj3>n=O ?N\)E e>a@\+AS77?%N1K[qjLVAgob#IUGIFa8lQ%tCBIYXCjf?iH.5]j5+*!k&DsG_E_H+Z"(PJ$+l'PRmA XO>5BpmN(MqiNP*A,@?9Wi44tbi4'0'W55LNmM2AZfU;DGU^l,g-XENS,rh"ZU$E3\=S&DAEm9r;i<FbX]ZVKNDr!`l703Cpq=jl^0;"8CIPp>K^N-]cF?I>n*ZLbA`2<5[7KBDLZlA1r1%ls9R;oNZJ.9R,]eQCnhBnF)bUL&L.?RYSbFONNqAka]OVF*#biD75m(&]@k6d5%dNiCs#NN=e\=^itmKL*UX )q\j=hb'J=.s`QV2hFD1K r(oZ(lmdXR7kK9`j?MN7,ghZ`<YQ,TtB7r7Xa:JYSbiCrXN8\iL a@gA[*!aE-e6pQ3o_ef2&g^Sk7'QH5cs<ae2%L8-`g:t^sG_B+g!92W*DBZ\:@1/47O]Sqk:kORW0F%A^<;W^/A%bkjW \&:kEh#7)=+b\kcCf\=(JII#_JN:=K r<N'^g0a_rc)B'F1B2%1OdkoF; TbAF]18 UK#TW>r0N:_>A Z#kS(V*C Y7bAeYGTpK%;tl6P!>Q1W!SKT\FS8hq4MV*:leK^H;N>pFkI0)F9K7MZ1Jpi8Mp2T\_(sjO!b-Eq2r1:[4%3V%gC)pmecS,cs0GP(/(l?X260AgGL9:&)hbAUX0q7Wl!Vk9$D3.X8#,COLJ^a"B.KbmT.*%eJLl'HM'i81@)>>qfq"HJ4IZ*e[&CF_FgnM]WT%;Y.H2br/ir><arAedo2\$3HdJ9I]8T8jm(88W9HPRp?rG4cs]g(*50e;0ZX?HdU] r.+TAAPXo,3DCZ)VsRB*>G-]="3TJ]/Z9&1i5a_DArr$d6ST?+ 606gF.trN;AQg?2TXfUmfNE0P*Tt&AGpK"*,,]\k':dVcTY:GPXXW=6\cf>C$F@-KJ$B6n2ZR6U tYkl-'1D\A<l=2E9TBINsjp1(&tsc>Z $"%O+e(QUcGiXAO8JtZ8 !K-O]NEbc&R*G)_:D^nfU7p->OA(Td05<Sj/%;M!dn sBZ=NFGQ8*'M#7]@&gG?sZ[j@m>*?\`A#D1&$Z,L7 3Qh9i)b=L737;!*a8$%j?Snd3\tr>gd\5tXUWs$!aB*-67+&l*TL/`G;c:^\L j=pV5:[,pE`tKNIm:"r%`b&^61IJ)$2Af86;=AFkQ'4H<`L/S'X.3[?VXa7@WiOQl'oV?Eg"j;m4Zj@$][-.4Ak+3DqADc8+<9rZ+h/%:6+OQ=4-(^Om*s"6hnAW_3tb=?H5>"f5k$bD]a1ULOWdf7I$/j6YeaFq+5rrJXWkAGL!;Cq.P&KD@IJR1 ah[nI- kM"l5=bj 3O4F%P8s\M4T:#aZB 0"dgA.V3*9L[n s>F+RW35/TO<.5iX!P;X@OVeZC=p&]LO1P!aGRn\!MiYF>n`ORkFbOenKAD!FKg.RNAl2jiE t;,;,i#k]n;SD$c+1b9'j471C!/0I RFm?:h,Ac_Pl8orLp4&A@oUX65JFZ7,;?$ZF$c)!Li9Lh/bLr]gCRKA#U)ZiE>g?jIrAR-d^Jom7ON9Y?^kaokCpR'QhF8M86-4g<TF8\clNT <WI3-Hd(;VkLg\V^AM;>=K?Y',qiqE&3F4,T VU8f`K57\j@!sO(Lbrm$c`GYK%Q$fn0P/,telXc->@[Bn!UB+l')=]A54'PjY3$-4870FO^0+/8_BDHd.2^4.`(/I.dOY98T0NA>)t^h;5*:+KJ-6#@`=B/t@hHR#p^m&k!;4K9B^4FMr &70R(ErANQ^7U 7E123;pZtT+72f69F>4;HDg`kAg<Pp0IBJU1]+cpM9Pl,Ae8X5Fo[Z9[r(hEd(>hLH@: slgm+_4Q@. =qXge<."NP!0A5]frD]s%/;TTUDfZ]*\p\c"HW$=&-#,MA_VE".&+o%3*P+O?E$oE>2o/&R.ce-ST6kE<U.G^PP<pHF?@OXAa&\4'.+%!%4G/?"IYF<@JM+WBRS1$"f;tLdK"c;a@,pAX[bc^p915SX a8,'ksR3:m'k9CE<1ltZ*"]4gmg]`ZFQkF,6CV7(-Q3%:==$$Md>ZG#;,8:E?b<`3QWMa>!X6NOT5CtIc9D9\h&YbD%0WAPh@#3KK;UgB'XOp0SP9/6T"mA`>CaBeebX4eCKBWtOc"'HjS6[.*YMZ5'm'R)_88g?P.cEnRBb+C7q>Q@TVX]a-DfE,;Z4n[0ZV:TGQF4>cc\IeJAlhNJ3`m4A.4;fOtMI]E/1C,<s+n.)bGHMoFpA^BZ/Q[L_@(2ddD2<Z9!Y*K@&_L0N9icXqW:ZK`RPEo2TM-14I&)d%)DJdpF3kFGgP[isS/glO7>%>UrO,spXDX^7pZe/B5@='S7ChLD1DiY]U6"VJ3"pUPJC!`A"2Whb4]c:.]4B3"#O+Z*4*%aJ8BkP+7E/jDcH!naD+iDmS`3QS%OBM>Q'cZAaZ!a#Hh?A(=H%k!;]/:AnH5o&JrV8.sZ%c=S0)oA-lG[4_Y2TT/KW@:^gtt$eq?q]R?)ZEC`Y!^O&/k,I?A3:]<`2:As186Y0PPBfDm34gtctp$8@F;BVd(,4h4[QAY-tH!TA*nY []?mQMIe^R"jrNMqs*?KF$q*00tT.l7t0M9;S>]MOf=]62.RG`arrBH.`(ZP5&3POn%=,aSEW >Cb&Zq51r/^MqQeX!a4U`H2]$$4OhKag8jdpk-JALjcp8M^J7*ga7J0!jTBPa AfR1_1aD"4@CUe9) k#T(*3WG?j2%-m8$3>.A02XQ$(P3>IC7AL:kO$7kJ'pdWi]A-)tlA&3 9dh@ L-!oa0r%7fg4i<\TejfAKt?FVHV9b&3Kc;fmBi`TF9f'\Sqo-J%`F8,;-&i3=B+F+>qWglV;!\T52SeM0X^D7nYjm<@1i4]j/X2Sj[L[5-8]r*^h2_Ega6##!<mVqc*E,g_RkN%ZjAJ(i]4:n4A>9Jpr`a%>+1RDg/9"G"@><RfJPUaE5^jsW+ds'QIDSaiYPc@mn><97=!nW>cg,r=HP2j:8Z%bM,3)&^R+=dqhRmLgL*p%Qd4cDnTJA_\kT@E=_^t<3 TbBON/N4p+ohs=)8d0AT&[[GU6rQ)U=@AS3!O.:ae%$^a:eF$E-B*)NC+I]RMb(OP:DcGh$/kmKC^Fa*(aQUa%<m.*8<;Rj3r:,t5e:\ghMEa-c)o DZ\fsc\/#Ue/Q pO]j?A=BILDDJ,]>aIhe@fTj`SO3p2hf^cXp],Pr+?^N?qi7.+PdZ.Mc7gKP".^,^M^>)Tkg,15F*OZebWqLVtmjP_'tX "dJgUs^=('a99?t%3is^Xc=b?$+R.TVfX7LQ_4ZsSs* V<E%#6d69WI>:bQRrr<="DSFR;h[*=Aj4j:3:3:&n$LA'="tGLIqr>Ho4k0[/k;$_abW0=ne4`NlXo1!VN.sA'5'eZ&;%9kq)#s!IAfo(KD+?ds*nYSVcOrhn%PFM%hQ*Zh&ArDNHq3p7TS&Ans>Z:;<OeJeGf+HmI69$,)(e_-TEbl$-,>@:a3:8-T#rQfUdad/nX&B/1%4SK\2H[]k(42sTnPa-om6ofNB52NMl('Wf\R;G!h^WjmtRS%`R's ?A^KUf<>E)aHs)mUo/U_-,1A(MS]C,0,3Hkk6QKWYOCBhMp"o.T/mi]3Xd8e9%296>X3>Kd):Fr41"T::Fg&<ht[WAFrshW4"bL+TmSsj."XRSW9gV:hBk&/'c.K_&G8tf.$o(W^'EjdR=m>k#S'JBX4p`d+5[V'T!rHTV!fbSRST$kr8^*s_4,n_HRXCOUb:Qh<:f.^A*6T@nb!eiPa$77Q;:-2lE=FC9"Qg<9>8API'1:-B=\_X=)8'UrRg<?mj%fRb7aE/'Q_TmNBEdX"G)KE3&(4C:]_$c (\83qc]!V\j`(B:]3LfAD!nq(0"YfM$i'(l:4tWSane@,_9V<1Ld">U"'4>V7Jr9k+lPGT*tZ((i.OfYj_N\PPQHXA23G5pC6NgFAYJs0#+'Ha`1hVf/>td- ]8T[c:qm^IkKp1*!c1)m1lYmKj@V"GcI?^ss;ZJAk%SnNfbPPI^>t:Bh-BaWK.l>W!ChHrtKEZ>ee_\MC^\C6]<:C$]Aa=PnMq(l%LsV`b&A/?iCoX;<jamM-"`(.*&;8'Ub0pM6Nc.Ua_F)ic9FIE,,1F1X-Fha"i#'@kO9P"X[I!oAXIDj)Z5Y0?T]PBb?HhAWgon;\ep1P]kO70_:C-6@%`)9N&2iF"Y>oXsj2Eh-NEX_'"$p`1SsA+Y;@/U3R"4TmTtRS1PX2-N(p(tE%E[!f54H X:=RX]04.tMH>kd"_qmXao4"PhQN [)2E3X5^KFGUs^*6nbXPPB>`*m_X"bPRr_j09<9&MUXsHee&m=pR[d4; GIhr<dM2n_H.@0eemZa*)amJ-tf7fY#ce/^ZiMOYQaI9q4`fHd\5ANs_,qsG<#`+l";l<1B*<"AC*SiJ`ljgt#T*_GXk)&(5FTY9`XLZ`p:h_hYhH-2YaIl A_fN+aBekG<`,nXK.9Z_WB!A&.7SjG`9@,`A7^d`9p'eFU8[H!9eHk;$#Vc1Fm&!DegN(W^FY4k(.mL;sFAZ4n%50%5SQgto935ehGtr=8@&e*W7Xb:2@ZZ!rV*34+YSMDFf8=>[^A-m5:MN 0BfKb"V.72m`$R[rbZAk)o r%KqQXP;kG6AS9oUk`rt#i\T4@'EhXWqDk)s2%VVKYrf]>lZf;4CrH&LMT-4_(AX"amL?UeerlB<NofC!2m4A5It^qM2.Obr7FQX ahmRtsr[gh[ c=knp)htn]=!B(q>:f&+"ko?:K e4m2!=LI55i;jg,-;NXPU3gAhbO_7Ga$,1FG<)lKK27]2468]I9NKi>c"&B4E%Ga!qWcc>A0Rl\EtN!dkfkBM@.+dS^`+nEAiaE jP^7"k5do[g*R"eZ!NM1_oeq+?E95+SRZbZW#mq/-p#jL65sA[TfB+V_+8YpG%CjS/R=eX]F@hf-H8cARJP-s2/A'A[s%+% _d_roE_7!J] qm>F1&7,=@0c%0o6NGP%BA*Fc9@jmKL_"Y9PSG"'FJs#Ki+T'cSb2 8ZA?:kYUQ[UTY_Cl)%9.'YjB c%[-c0/h!S>fOFV`7pFcXEo$/.k^JA:XAPqg@\ ?tl A(;C,llcO%HbKGJiM7);(PK#*6"df'QK@7>%_ils n(J=\(=2mLPK4#@.k_RRKX8qAeoR%-'4(#cF!Aa9^kiF8gInAM@1J#cHN)D]eUSh%.U=4K#<:R;]ApDS!N/UAA[@KPPQG?j'-5HoMK"a"P+=6E\#a)\/'$XH:f9AK6lAPk=HH6)&a=,[<c_('E$,f5CL2kVGUYD<;/V_l>L\[00iK8Jbgj-lqA2jX#fp^Vn+D"'fWg%pGM0L;eLW-]]k5a/fhh,#7`75hhR/a*L0;3pQ7P8$+le8YQ0$lGoObrc=N@fA`_m`^S-C-:e"!/GZ@"g2;(+*7AJ*K8E''4_Bh(K0;,)3, g't>enZq/"VbTGnJ.r`9Z<eViH-Y91GeV^n0VmM 5,NL -ZHCAEAilhWW9W\e])(#r:W<A.4rh6kgMj`9cI<@lp')TmB*Q% `L8%^!bc&W#@#*-iT5</f?nmFWLVAciR"Zd44T'E12K2J\$5*LSUoP-ch9PbP;1 X@=4>m\P@MV2Pg6b82'$X5%C*ccs,o8>G'2Vnmrf%7- Y<^>TL#be(V*ALae<3r30r\^=a#^o!OA"@F9=CAgO^nUC+*_%b:VZ<0ka>XB#,t;4]S'Lf[3j)7,Yl=TrK KmJ1@%QebB.J7 ^F=g)"QP,LH>45bAF*l @Jh<g4+[7M.G1SPE/nTA6PfmA'GWU?XXkL0)pMo5Z<Ap=Oc@`A;5:)^_M`#"gi=@sN2o(:L&6<=)iLhrp1[E_=1=tf^-Mm^?>!ObUpj;;eH](mN#gAiYNW5VrcfCc6GV*aGnPh'S@0@0;K\it@r`lsn`hWXa!mQ"Km gtp-:^;>O-4kHE`*MrSq)F^0RI<8mBbo$=0e%;)YT&2+?(!jjaT=2Qh+nr=#078':9DA9m7 jH3gh5YM\]XBls%gibpM;bm(T)ResJ$LGs;W`!GNs7R387UL3@CoMX^,BaUT-Xaj'6$,30i/VlT08Ftl^R M>`ltK`/?.N,MLGN]?T:<Hl):)U/dG@X<UYae!:lB`4X3S'U:4]ZUDYK\aFQh0jH)1fj>:Ap'k16(AM-KPd3]KQ%/=eGFLi`UUr\:?>A+JMa=C^?&(5GchU!AG]GlO<`(qinQg/2t7;E[Q4>8^(A[>$MNj4=/K;S53Kj1_[(7%aL$.t^XltDja#<0,.#b0lYG%$9SAALMIcSoa7Gl:`G#W)4\mH5"MH+WL7FF0EtR6K'.^0Qbbb6pkdB<bC87nI-"1?QKmA>>]6/Fk#`MPG5BC,V6BfQA`gpEEs(*M?rl>-RI"'b=jEAtl9J5Fhr,BS?EN5#83F<").-s^i<G(pF/=BbrD.o;hgGmbSC"0Yog9B8i,??ddI#/FD(WZkI^?(G6,$2[nE?QF+THAUsc*SRE2QaA;Z&'d5QFW/F/K*HB]%VeNK6_'XQ>">GXVQC] 0cAL$p01/sK\ !gR23"/_nA g5\"'Q,(<?VG_`@;k5$6-Zd/'99ilnA6nrN=!O$]X>mW@hMd`<n09-A?-?HTmGjP`trdSt`>;-S^A\d_d=PP2AP'VC48n=&[(jA\Y0DRiID>6$hAN@ M9=;=Do7=MipjH\DMefN/7Yt/h/e]AZr'6XQhPVL5b/.?Y;S6h-cMK`-Znal'^>.E>BSW"<*!)h]TgMVSBeV<-0X&olt*fk^3T1otA@N>Gb,Hm*"MY/%e5[j6g5PFUo+.qO$i_1=s8mf]I4dRSW:4da'CG%"H@m$<_cC>*#@V\k<CUit>TW6+6i1&Fqa5Kmd0LQH7[EV``MZnlDDoTjQfU[eXQ3RN=SF+pVc5o1Q:EH4gojn2$Eo&Mf3D._j(`fcM;'gQI>6Ec&qO%55jKt^'5AF=]$a".(A_Q(p_KhMeD<f;/Mm;s4kmsXN\Jk"h["%DKX5g'N=k$,IkK+B)`c[VUrmUM C%$82XHqG& f]D'"T#<8qch#mNZ%"JB@r-((;!HJ!YBjZs29?0g[;U+WUn`LE^r1YY& /?U7i _.(>(mJ2H<pKn=kDM]_Ya\lY8.cH,5<V^6]b[&+tp_Tgn!+MZY,]EEo(k%(gX 1\bV*,U.&>)=gm$L"`ED1hb.FY`kR2>FcS6Wl4(7*=F9l,4`TKEB=(5Rr5<A5?;KC2Dd\]K!rY1)jtA3<$T)!N#;g\fh%.BisR3AhUHfpO52X(t3fMthhYd,br9O[E<EF*I?U/)T/Aj\"/dC2BQl;3XW+k(Xs]N1be',?T c=XCf s`09F2&Rh)*.4bm+-&-GiNnn+e&ed9X=jC`MSA3j<5_ec?Hd)!cP=f/9`]B@9c)N`imVYZe(pT`4/3Q))UG4%t$&+n(F>"P ?h4$f.@p"gQO[C>n(gPR&l>gU/I;.PU1dF4DO?%^m?AM,aUCGaP@8_>ABJ>/jW)m4,'jUWTFga=LA9A6GnIr[*r9NDRPd,8\S%JV:b?8J"Af8(tf*6LS3^`_sh86/FZD0h'.OXjmoOOipn_5@6EhHgg3Em/k9Z>C< <tl#0:CQi:)8Ld&@XA6LfKJ%E,Y19X>jP;[EN4iLRPa$\="`RLH/7NS?OA /kCX/:Kl6A[qZUrl]dgBfYB^WjFj[Ho&`9:s8a8ik/ ]d-=[6F[*>30 )c0"JQ&!n1pde8*2Ug?0"E>S_1+lL,eV_>16D%8iWW%?^\cbN<Jne<a8:oZ97nO>C?hQ/mNla l;fbt_!NqG!!2rO\=pH  fs`.=XdqGr!AA)H7H0lsAhj;O[I*F^[T"Nj <,8'1F?U\': ;JB=E @L0B&&4E>k^=oC;<jBb9-A5 >(ARWB>RM<J#Kj#"_X?por7Gb@D#hlmUmllT?E%3CJ:6-/$&[j &rc:1%_aM'DTZ;LE&qR6\sr5s2^1.q&hJn#D7?S4rHR,^p9hGbKr*Ga=!QbN;1_7V&ht[PsU1:o?2R9\-emDL,0PR4t?,bH8Btb62>E.iU,nrF G_U-IM!MjZC:5h4?tfT_GFe??DS07>U0RJ(r6&RtPR]GSi ` L!aebX\<#;-L<Z<"_-%tq^sN9]7koQ!c+qT]j* /8l2msVpt:3`q8n+JB9"f*:?YY`1EOO+sFVA:YWaZ.'67e#nMk!mQ;@Q^iV1Rg1nf:N<clPqrQg?/jVTFkQH^1lc/CI`2?5gL16R]b!hna0V"'*EQB#F0$9pX &jS_^E=8can_`DZrl)0J*okpR8j,n1fD="W]4e:?UT33oBSQjO"ga*kO]+dB2=N0#mBRY.%`GR@!?$k4D'6knbs$@4rHKRU2aI6<@O]D$rWEh Z?Z1[3j`g'jH@FR=5S3`.,ejFG!aoIm*?*FYnYs@j/VB_r\h:K)Q'0cRi?JOFtL$("ol[+0E*YMF1_G$E#9QCSP;@*:P8m.'r7O[+EB<MkS>9ZbAR3f\cs0aXj=/I(57(P27:)?i,%[9WC##2I@l/MNB Tq4g^@PX"f1R3`)c(G?AWG9]UUE\G9&s&05dOAJt"nmF7I0rTe\U"eUm;H&]Nb*J ;k2?fLYAetX7.FH;qhPO34e;dq?_6 4W\pQ[-b0]q]f@8rSkAhb,[0)N3t\CM$%I]T@J&1McJ*QQbK_%:tH`2AAGo/nAN_Jms5N<P>f2Y0Qs3k`<9p5Lm<R47O)^$EMj`B=WXIIe"U^qU[83`ACkidXHs?Ci=(Hj,5jl(NM$lXD7W-P\ /"I&J9AEo$!,;YndRW.Qp ]:YCk+RAL_&p4]Mc-?_k^6 Y^`gYe_3S4*q/pq>/C1[N#OGK?42e(7Zg>J%"jT<J7YQ)$f$5f)^!8-1P.cc1E,Jk*"?TQF4HV"i?%aEc/aFk"*.s]^?)]tbC)`iI]R%s")1\j<0Nd)%SanE`(p5QNlg)B#eZ$pSs(GYmJNU-R%Id8W0_.M9dWC!8JE8crR7*U]e&ZTfQs+O4]?p&il6)qA[?G=6iHd;DAm"K&9V!QEJ(/JZp+1G]lX *rla-K#Ji@B1UnaPs/#Fa19 _["Y0K>"LE]pJ&fMAA,Up+Jogd#?A+HI[8m75=C5/g.SpQC3bkVMlA-ne\9Z%^Mb:G_*P>s9*?l'NU_OTLIQ3lgp$`T-AhF?Q8W,]t;j?m^1"C0%L`]9l`WA%A?AEhEqagE]l*c6;AK7HBsZ!O ]!BSebksPB,p7T@Q>5CIsRh[:1Z-*(g,s\I8o;ZFbE[R)QO>&.1fXW;XUG#7,ibDMQh$QA#,cO\pa&G]c*"2!rZ//k<WVRCk)t,9Z1e((-;5r)Spe _"#Af?#9+!X#q0OF-%C;qZ1tB=0LioQ+&W6I.tJH^[]<jUOh(PK$ql=dNAt-Bl<-e=oYcQXi[l4sC4Q,lF`,@)*9&2EpD""Um hh$b9qFYURhlre\2&eYe)LH%F#1$j3d84^!ImdBA%/ccf/<#Y4&eGs\\d9PD%_9gdJ>0Z':#"mt&!)[(./8VSA\X8%teD@itpI6 8lQ/1^_]a cKtH6o%*C=AOC*G+Zh,7K,);9iVc?bm:VAHT?/_*U\mAfAm)oGOA2q!6!QJi4"`hsjR36p4K+LA'pt[J;1tEZTs!h\V>G<,pVpA0B0"D&ckk,QCRX]K2]*BU>8![4U:o7K#F3$H4mI"t?r=%3rj7_I._+CBYa]V_"% n%9cN\)+FH2^cl3mE\=`)OLeEKs0AFIFBlGtd> kT`s4Ql9A@m54)'DpL5J:Qc3:gK/`>1AfWHcA(+6e>P&]9'/<Kib&\h2Cmrh4sA<;&Uk!G'..MVl`DB.808ZiPk_Rab@HcYoJ&Y:or\gXkDl(9d)UA?0%R31"V`qX*?OH$N\KkYGrBU*b.2#lGYRK)g!B(-U3WeS#EM50 aI<XiG4*p6<ANTG4,d2U6'l@ScS-e_%Rq#Yt!T3% @4b0\pE"X37N<FO4ONP[C=$C8RO%%nR]Pcsj!AX>0U`(NpFd)A$MIFPM'ansaARG*TH$dHp@@j$&T+]A75M7)+gbBDI]ACmr"E8kDqA$JqXpEtH3Va?QOY&!A_=/=7p.&c<pLfKgIMNg3L.$i$Q9V68Z6Z&S(P/CDEr^Z)*7jUrk<LU+EVqNG"KJP ^A*bI:4PW<bkBF_dg:#4,I"E@9#Xbn7piL8-[T?GmW/9MSI6/^OZ7h>G5_K8Z?+H$rdV5p?3ATY+.ea+k[8-Q;]!V2\AAc5g24:,^MW?hc= 7tAeqM='\hjSp.?p:O2BF8$TkH>#=6:Ddd9,RDqm61SIQ(+_d4">YB9et:P[4s>6>ZYeL*E415.\=PJ;eWJ+kJ3':`s^H,<t<=gRp$DiS\A$"?*i:3\r/'^b@Aa9%"BY6p1:AMj(EO\0BjrmJg[U$637drO:=m\U/Q+_G \Y@nV]Dth+<[& d`[<5;,Omfo"D*]USf&R[q_bW#W2Gpp3/!AtbL8J5)Mo(7MjTB-<e,git^8m;oA$1/SkGI$#I8ss+1OFKglHp#"FS9Kt/cUq^r?7sA$9/jZZdT0lR*']D#@1=/&k-ASk\mm*bSL\"@PW+M@'gt5qs_@?HW/V%%D=T=bO9OR9aT#*_D4h;5fgGY6&t-sD^]sne/9d0j7+[YIgA4kDUBXM0\C0jC&:Mml'<6h%UA8"2^mCsPWWPn/=jqpX,HK,4Nnq7lHNUeg;bZ^q&"8CV):pf\\tRh;7qa;dh'46Mr7hSJ1.6d/`_9`CrBL;N]Q8QAWk@"\'R8EtF(W)$D:]:h*t)lcXBY#8"M/8'\g9ARNM sA2L-\8JAkAtAYji8Y^7SHNg@aJ]ZqlN'sBa(ANIilhM=sc+2YDZ[q`Ab`08Qbe9C)Fh6V&aD.PWs$hAK4!'I-k'Nc:jAEaEUsU:nPC9t08=Z(9MDJ:`1oG+>/7:iY1=Ek5UK^8<jN\t`-R,ZAb+q(L9f_Q^H2&k-;iB'\:'BV7'TkL9]Zl %)E5s(J\>CnXV[@^ dEACT^^;0^H\GUFTa@oRb-LEcKo33\Zl]0*`lWW4:"SbaDkO5)"+3X_,_!J5c*Qfb%X#Va^6oV_/V^[%IVlYI>r)@,*D%dY;U+B[`\L&J/XBhMg9CrTl7FrJBJ_$sE**8i2ae:E68aGQVX+Om^q\GM6q2F[m[[B6'h"lQ<H>.Xejf,5`H%[Rh Dhg59IPkQg[@UG6l->.YJ0PchkF.jU69ia*L]NBA^MLliPJO*UI&AZNDf%qX?5UXW_1:AOFkC$I$Q6/"RMZ?' K;#b[7IZA:;)'mn9oAc'1"'QM?#!IfT!tq+<\A-51sS^s97deem-.JT]q)7S`(N]6,,j#8G8TCC/M6'tjhLIs!N?7k`F5jsXQ/^YV<1l,#![c`mT6F',B4 ZRb:=m>!<Ff\LnA)'-&4sjK+;;JK:5.,Ip^,PT<?o#,AO'":.q!<kZ_mq0BbmgNr\6&C%P=n?A&EQ;MEH6E O5]A5H5n0M3,T.@Ll]rPZbq]1$mn7MAmLXT!4Rch^Le%G.3WU5dg>Fq;jfLX:;9%tQI]&NDA7U1a8k=)"AY5I-tPH#$tCOEC,->'se."W%R"\hAiVcnMr[[;,RP8#+g;.1TYIEK`&NRt^MoF7f+?>8`k 4Vckq,7.AJ*%U5nZ&1<8B6d 7U#aK^NeRQbBDWDhSD!?q ;AH0#[b/M$0Stjd?p[*rM-PR8I=rT,U(/E;g<I6:)F?N <hCd9BGX,6FA;?GZ Uq M^/2k%iW"FjJ4@\ja`g-2a)H3f`#ZSN) O?9Fccj(3TXS%O'+D1a+TAj_=cd+K6jH38)?cZ[Ftg?<Zn20RQ+*a=L 0PDJ_HZiDR8imqX>P/\@Q$ZO.ec:)bfK^189OANN'iYO=PEe!99Gek=2BAq\ctHAfK"A9B/Qr#"=YSY$N$;OE"Q*Hs<;N_OkJ>U:(BSS[NALge&RO5^]XqCJqGoq5MX)b,eBV,6i]Q)a.GcMpK#E8ZEALQj`VT"nA_VCjINfki8V1#KOMYVs@6*$nt". s^KA<ENce=1.Y,aC8!oMU`,It+ch!r7iNEiFC)pe3,0tVBWbD7q63]Q,TI,-K;\t!]g%:_i\o#_a`<.2Kl.e3+*\@;]AQ[jq,]d-Xdf\Wa[I9Hd\?g6*6m4aJZ: _UII lHOY3%+b&_I]6[%q1Z%daj&^Hcr1Y-mE<X1`& $R!NYjt.CdZXi=fra:MJpSRU;B`LA*\Gp=cA*]cGp^=JS/cUe2'b`-B/i"/cZlC^PmB^d4Df`ID7XmAN@M#%BWJ9[k3-^c+,n.PW.m )OnT*Z7WjTb'q7sJ4*/F!qA7A%:([<nWsR&%4_tFJ<ikBJ%&')Qnb`I/TMD%*+M;eB(`!N?<]6X>(4B-A%>H]`[Z732#CRNFEZX0*XmWcr`V$/#DNc(a. N 9NY&-i!D&]ET:/pB1<o,#!UY+<9jFkq'-Ma"JR]L!HY["<Z8#W*ot*WQ XW`t8''`$9VT>AFsBQZ<s67ITFhYE`m2H1V_V5Pf:IM5o;=8Zf=U,:r:`tU4p'MA?QRnZM"nPj,24).Pf'Y1;3jicjP#9ehm!MiGGbHVajc1A[Y<i8=/+8?WVJ#l/KG:7H*PoXN/BI=S:!U?6_ob,A$tmQ=6to_GX@?7P'JdKBB&CO9V(Bq4<ZL/'d_J+"#CW'b@>0>.U!7f4pAn_rgO8VDWY7ThT)H&3C5:T%@AqIK50Bn2:f' oG]8^$Q7VQ^N=TQPrEm)^IIbDB\oA;AXk&F<Ic7^kj(UaT0E5NX_A!iEYb1'?[TJ=Z`9^!+=Kb)TSIZ`fab>;*rPl=CM6-5fB(ZJ>#l[+(=0[HXjC='iaOHfO"^BFjN7YB'o[,p:Ei%HM7&kZp9"403BHU#?GPN m+r\2j`,T*XL-*d<n/5gnN0).DnQo#ceG,s,6[J@R\1:!d?$=TYKjW;j`Sf0 BX(D\!F e:$U09;k['6d=R HCZ5s8)JHc!3SDSUc5ABSBO6QRQ#:enFr2*jXoc[Zn=H"%Aa,M1+LE"S:4TL(5EV==C_j$pj$`+b6i2+sX12'-qo&K]!^.^US"Y R[t#3r8Wm0g^WndCcle.:6e-2t4=jZ-eKS&CKsU?]@a5U/9W> LabS7 Ke. AtPe+9h5A:rBbLDU&MYk,Qg.V;l30V@jM(ZsZ1.Ic2A[oYE/Hl`8'1s.AOC$* 0q(^1At6LA.7Pb1*'ElHDN"CZknM&pK@+MG;2r8SCWF3g'YRb"!CcY!+$rc]Fs3W,jO'dFE_7Bs;W2`SK&qLYo=?N<A%<VD!nAo[Hj?bAf_A*Af*PpIfE4Qo*9RH)RKTI-gdD6/Rl:G&gGG.\t"DeGGm`.7oJ?#?3>8q8<`CE$>p0h0pk&E8!17`N7?XmSEZ4jA[5]&99$PaNUH(-biCJc.IGrEP*0"Y;J%/Vm*A`mmT2KN)iS%BG 64Qk?@P/a-Oa6f5@0W4*I>"eM`q>X)_-L[\mmm9Zqbd+#rYi&%@\doT:s^nMTa5]].d?< _,r"D(E5HYdk4GdYYbN]h%QZDi7]oc+l&b`Ld>o;]40]V"V.FtPF`(E`nE.]c)=NfAN0<&+cRhi?>[e1/i9m4=RM&<;GW:VYO,$8gb.M;4>_7<+DM+.9/C_[F`DC8iQ<qL#7+sVV[kt$mTKXCNYK5pb'LL)n?r09Ch".]j:A^"=sFOcNA*;d<`K<j,CQpXHLqTUS+?SC(A (CHbJdIl71 -L2)JSJ]8)`*)jZD2apUJAgS@CqF10K=A"d'k^=BYU_rR8DR_H+Q8R`8:I6AD &F@V$ZZMY'KSldU4F[%lL7BagH 1`\,A:BnAMsJq:,Xb9I&Ls #GR":fPSG6)gmj@BU&amZh6Z\q'(]aPDq>@p;:ji-n94iBF-D8o'pO%9%ANb>4($nEgT@k2bGKXUNp=V"Y!ZKfPr3BjT&cOLLA!/Ne`o^+W02Hl3J]_9q)AEqE)MdYf;1tQoA#N`jb"*A2FiY!-E#Y(OArJI+8?#$?Jre6gmP=R#bc>m"/[U0N+l# k.5IN%FrnJ`qIerjU(:D/\ZF5l4`3qYppHj?q9A9M rVrM5M!ng9>Z .$^2Fs Y:tr/AgR_]^6^FRi+8#kss[PBAcW#KGe@m8?PVRq1A#nkFNiT`_QfJtM'M-sBDdDS*D9b57SBX/e4hR+b45<5<+X6i22k3LP`.X1:gOVH>#m<k5'Y2g0010lM%"Cb=]CV70mEA@qCE'ImY:.$JEn=pn`m@CsI8K<KVp 80GVqkLeCNeBE[>jAcq-jU&f$30$II3Jpl76qKf42O7t,s_%NRVQhmQ2Zfh/?bX!S+f6:A2O1OLM4-o+KJrA1d>2B*\F<Jgh24C4*b8P&)[aIZWCo5,%<W)T>@o2g25^LYfP>r,!gB.DbCs>dfAn?p:LZ2V2o+&$XaGhB&MBZhZUH)oXgD6:pn*(0j6K=rH;6??\Qn7Qd-XmqlA.$YE]`54cOA3(["9-*\#t&jd,6eaDA6"D,\2D8"mCM9$S*!YB8A! \<1P9MVXgVjp$V*ELGEY*>2%EXTrDO]^.9m:mmh^nV#,o5)$2.!["@N5PF`:(ljL[^ES^"1V5g,*%\UfYJAlssgLlT-+b%kqJ hifHU<e(8nVIaH1Je4MZh,Ie5lhm7Q=3PcX`q3395hmU;X<<f5An^TseI[C4bZ@g(!a!dcBl<d!+,-2[i*Obo4Xk2b_]sg\">KKTc1`hB&3@Xf/Sj;((5HM%j hd-i>k\4(d\@8t1gY!Q2SF>t*O&Z[?QYdo<mNp.om6&rT>I_K%NG3"-dLTco&-,A\LY9s8SX(K_S86Q[I E0*;!HU-)Nr* d1Dhll_G_O[c6^"3U_6^`O#]8.6lF[1AZ=8&lF-TSp9N^9Cm'rR_dfblH%KZlFl!Q1ZM]`oBi*YA>"dJSO2AU[5/R+`-QI+cl(08btkfVY^$)TL'7W`#,[*Xg%.=sgDW:D-$!97NarD.k"Ya@XWOA:Bjb<B%6I4p7cb6q(*D]0+\Fk%g-2Jfif1pkcs(!ahc.+EQE_e"?=H<`[Tk<ts^=K4bX;5lMB.D%jIGc6AHBc\gUP#:f!89g-%ato` h>TT;Ne>bo=?cSkQ/ n^lSUMn6k^+;@]n`0&"V9tqlOi>9ZCjNr#bof6(12\^@fEqP?F3U!W;6D%WUd[>.SQN@,*j:g;g.hL==7YMI4$[g\8 cW<.:8gQgI$n$=+kT F 0`"e+-mp9Nk52!"srFN-hh9ft2 =[q7YDdknBcb(_??0o] K\+35LFQ+SKUl*f^8G`b1 R4NKb\4Rfj4HN8V7>"Fp-9t`<R*H-*O^2QTEh6ScZ#o<!/D`C>B AnS(7Y/40ohoYI`+!Q[2(s5aSOOQ;0gA5-M_SEF=0O/4FE\!C")m:SC"]@^6=%6,BPGNM2mc'Qf\8<=.sKAM)Cqp="[(7`U(QL*+JjMnVo-d-J"'0,gWsff6[3/<;=j@^Sp? 47p3P<&HU;2G0;G[QhJV.(m8Bi!DA&GXQdZ4>kr9$Q?+%4ho=WMFE&B4Q5=AT6Yr9%?[4]&6<elV0,,p<?H]f5MQ+gkTIDhq$^5PnMgb>[GMo.1o(gj#>W>]m6g:`_DC`B3!kD\-/FO_5/iI+5Ls[p2A_b,8g_aXt^g7ST!"U\<kJ1CS.c*XUDphPBonh4>a&AfN=UF CG^X7I^5/VL&T7pD]A:E0PQg;0R\Hg m&jW:= ;tQ.A6=F=<D-A\V-6Q$\17LMJ6mi<Zb_3btq%QOR>%:02SI"9 ^EZg11\e0=2eF^/ZSZ#h&bje9%.H4q@'p4*YrB4+ .ZbA-CdN\30^(JNk6cKJ\Y"EKH+STS;Z:UVSA1mtd M<Dk@:T<%flQ.\I:2He=A[p'I"?tSSO9.*ded%I]>Xd>*hfa'(A]?p3'?ZNC4p82 fn*eZLC8Kp:)0@mIj2)";9SeqtBB^+42=Nd3Gr^Vns3<-"+WF%7$ge94WS"+%[;^#8Ug%R&spIBgUX/HJ(^K@BJTeFYGI:jdSNX1Qo&a.OgOt70s])D ?S`\<#-[S[W"aQkA0m,FaN+4:_%F +m)a%BHkXB@Y61/0 YsS2>.NlnYZm3&n:rQEVZ'h<4^/M[@$qaXM#X(O7j/_iekr,*7M#><$o:f-3D:mUO2gTK82A5,a.IP&ScI+tIdM$)E%T]WnEooPL&$JqoPY fb^D^&.?\.c:_tm0AE+MB_B.'pnltbInSb[.o8!2)I(XA3_+a?#DA4o[k7]2%,B]I['0eoZ]t,,sXd?D+AGN@-9c/2Q9'p(e:,hh=5JZjZMg6\_.n$#mr9f[-A^kY%@s(@Z [8m24'C!,q)=9*Wk$,,,W:#\?HmrlG];sRATTY!29P`MR3B0Di&b+_h_,jrA0:E54>js>bs%8).Al9_(?6Zn)JLa]S9JIApaomLeo0$sDEe0V0,WVe(WR>Gb5#^J$n+7_c=V$:l([4G*eX=2b3pJ<*j.l<gA2kc.Ai-#A8?.A'\cSZ#&WbG+-l\qPg8m#@CT(dLiHD?P?ONMt8G/P W.V'J:$J/B-4MOL<_eq]r9(/05Pbrmg*,X[KX!\U$600]RTq0Lc8!"f*h7C?[l_q)b2>='>A5OhP\;D1nY%91q)!>*^J0G&1&k#*3Spm^]3r.rHZEki),`@4CI,2>mJ"QXYP&k^nI4K8:G/2Lc!36TC$%:0 AAgP_D']j.)sQ =80_XNqYt?E<K:e`]L6im%"8O6,*RkW?F`U?1(9?'smBAW=5mE( &AA5*V+>#S59#CR`B]rG';Q#tj^LJi'SQ&od9WnN]CrNf&h?n1lMD[nHA>3FV%=J<e8,IY1SfB59^%qcqe`]#@>rh\kj'$&$"YrQ0k$2I:8#.!07cL1#Y8a)K[r:eAXSOJK/aW8WAd8Xd>hWLfrDk_BPN XW4<D/F]R5:Bo2A[X<$(Bf>4E]h:#ai*4)k%*638_nj^;grgpV&H%"4Wti8lG"J@>J+M)#hdtZ0E7<SZ6BWe.^G7Q#mm&l/l2Xm^6F2I2C#<i!pg @Jt+XbXj*l%_h<sT]fm-RTM.Q!%(pI`[5ZV%bbR))5"h!"eMJKRsjYb=T8Al^1ZXioWg]H4_b"-!ttnZWtS@(\%TB:1->^?7`Pac<lPq9!%&5d=LNtAi+qAVt 5?n!g0GgmAtS7Z4Id:g1 AG3("<s8R&i1e_gge1HNEl<_qM_LZNA4L8t2ssC?''$i"QMgQk?Fa><D!0+<).r7Gfm\A%>X48dPYEk<#TPH)$_Q#,d8qi`IA$!ZmYB/rXIS];mFSI6VUAr`om't&oa2g`th1F]?4\G,o%>t3b:4UgqbtAqHbS$#cD8I8k([]Me3Gm@)Fq\H"$V(s1h?>_^Vc;a9]kg+5\)^+MjVj07]=JY6mlk9qZ_:g+Jre%+T fQ.cJ9TK%YG,71(:kV74(Yir%i$,`g#?sM2Q1a<]VZ07FX/A=qb[?1KH!\nSq:kLTXVBmW?WY"c])sTX<\6rGL3FiRU3.sB<60=/,h's3N=>qs5Jit;O?nEam,7757l=6LA-.mGbk3:q]=#oC8S_$c>mGLEio1K^'/h1.=9pBB!9a(-&VgPglM A8c14j1O/'8M\M3UoBUccC8roZbLOep$ND=bjQ(2%.1C"M$L?m$3W\n6K4&7S!g !4,`pEJ4F5jAY$E),dU&jUiiC4><&!rs<)#?JoWcc6IY0qtb9%NF\/p89FWK>WH.Jq&HTdgddl3*T%N]0p !;"2GWLf[O9KWhs(h@Ac[oj5t@$P2M.:A>PfFi;3*Pq?%MX0Lt)hL<j&a/9A3(!>h5 N?D!si%hn_Btp2Qagn>T\hU4gbMiqO1.'gaJ"ioTbn_T+M%hgGPmU$<0Q*4rnt3bqR3)d3kTnN0m\;a^W<#@MtdscIR'HZjl)01*Zae(Viob5FC?O[#UKK^Z']$CjtT8B[O/<Y%6KG-/g6QBZGBd`;;.S;b7s#>p)h4Jm`k=2c*B=R$6EX*8I*[jgd,>)sp:AT\fAZL?G7!fBimJ6+:O(j/4o+CX A")c4B:8=Qk1V-WJ.kDOYK8th[#Rmk&=f4c_f-R#K*?U9%,pNKDeL+SHmbcL(6]Ti<S4;i5NKcJ2&lm$C%?QgT141 iPob=k&RYraoEj [n_gdRDGnc^qW2srXg"s")HY AAD_97N+XYql<$@6]1<?!N*Ys=;?03m</hA@`d?(3[W4>?Ksb@$='?!RMK;IAHH_k R`lWbJP\B;XAH%gWptjHrN['tc6h!$b@ l,?-JU3M\WNQ/M\Z.k"c3m#R@]gP ,WAa/Aj=JCg2egdf cA`_K1nrn40JM+[OFk:<LFV:_r#'XU[aAN#P)S!cLibepIU3[k)sTL8#]r?Y0WgmY+O=nhDZSf)7:s3[TETO(?@ARn&_5^dY$1iBAbW"n;o==]BGCEiRq>2.3J5A<71USti8Hg*%TtdXPj<i6]JVUhsUA,=%PKQ?8tIisP&FWqF^%ig7'i1bM'iI=i!7a*hgnC1tjptFh=A<Z2<C,H-*I*9@% T:@8V8 ph:\1)corNLn'*XG6MZ <U(d/En>4"RH9m<inJGY?t;L:(-J9$iP=GRX%+h]m cdce[HRQ6q3,`nLG(!@RC6>]K?kR<p<ZY-GoH_i_>cZtGHA8ID/I8fRBQj]kB&\mU25<"DTp#G.1N?54i4bX;(kH17'r[7]VUrNnnN<W;*53T\T.qt99Om%KWT1qd*I`b[-f\7F!-[jntYYAMsntXA=>! H$&;>I#oD*&2EKF5.44<GfW@qjT]GoVC>;Y1j0[08Mp[n$+/eg;Xs\sfm\YU+.XcP>?sGfKd3QqC\JRS]ndgoko$'JYSq_/QDfAQK?9fT2BW83L*1E8Hf%"@(]Q Q)2=g47THjh*p(_#o29^/g7`/'==eRQ0[Af0`?&^D]DM\!?:+J X2bG>AiJL#kjd0_1"IB%)P'5o2Vb!s`6ASOobS=GadjR1q:MJAAdtIV:lL8eXF4K;^\iS;f>5fF!TD.tGSJo9qp,]!)YsSn3VsiUtqRq!01`QG he7)E-sBRXgM67Y%rACGSM1EXn\R7$7I__*kr0A8"3F?17i%4?@(lQNCm)acGB;G3I+i3rO)+2"T`J>A8I_B=*Q2:Qk-mdJL^3]8Fj0t0COl^Ln )YtroDj?J_cJ*%".F=Wh$=tO-9p#="/Hr3n<`b)03;iOXGGdDNAEFA/s40<kZt[/dN*7XTj9\m'9>;X@9jrk4=Y>7^V4s4e/]-2%cL`/%H.#C/66h0aNi8W+6BPLi![ n_OcGFibhZ1c=sO^BRO8JrpE8n\15]l3;9Ra?;2X;c=dTZAkjJ`sc@SIAkoBIl$QaJS&,o"B#)(ec*[ehJ&?ksoSn0RGC#ad\@WCe,&pDS0fmJ`KE.iod_8cQYgO6p'-G4?"\-5`_bjs2V)t)3-Cf:SqBh+r_Sl[8FJ+sl:NIOL*E)/P0 9<M_UdfQUpo7=iDoj"?_#e3R^J?)%WMX:pUPZ(IG=UI7g^9AM6<ZA&c1'\k3=P>\H)Z<$c+2fk,<)$+=5UK 3_>]QWK,b3X_k9EI2Zn1.OAJ_+Kjc:.>iLGEUFV#U;DX";n!SG16@3fcP?[6JMlPs"-j0J/:i+1m":VsTss7E-M\Q(VR!;R3#SHSZl%JM Y[@,-(n /;"h]WIIPk+ UMD1P]gobmSKsdM.J4&#P3M9:ErT8%A/A+><`oO<"0=LK;c2Md""n]o_TbOoESkPN>Fr1PdB1j\?5*.V,)RAJWW`@csFaSWE>cT^PO3EL(=K%]=3ld;$fISk^0@4<t-A#,1*/j:V3q ^7j<Z-$)7+"ne#.)Hln2gn3O/rl6K@h[;AXAMM$jTtaT5YYVGCe7_9.Q*mhaKJ-+jNQ<=jeMU0i:a=UlM4q'__]H.PF)rVA"6JPP`!s$b-X5%R"1A&g;)ZAf7Hel]h@X ?JAT??H\XVA!kk;&Bs5c6QB3^BXo3gY'oNkOnOD3St2EZ0gp]!`.%J7CfJH7+pm0$Ns Ocs76g7?9#AnUQZSbR2ZV'+-m*qHS,:I[+?(%_1IRVW9&K_0W /9="$S:dYP_WoOK%tA8r`3hAFlT \:NpC(6]Je*T1QM\V0-J"6q.1AKrJGH-S<pqA00hDVj_\jVO9d$N(.rUsdN'<h]%PqmND(e;+P>0)o,P"W__$Z&Mhg6=.RDj?hB`''9""+8jeI5,O:s4.[ODpEbr7cL8YA#*0l[0orYp?I]ld!98YXkL)XQTDp:?Q"b<(gY-L*I#f,]4l_PO$&o29Jh3)5Bo^FLs`mbH[F@kNNAnIR:aR.E7 !2U9\1RiE+<qBh1bfpZgMXZ,:Y,0,?7jIq"69sP==ksNkrPK2A?)os_K@_ A^8`SYmX,aDr89h2KIrsi?SK0A++,3:=*lo/V]7*%$D^r3Cj>ml!J?ZTWK88Y=gAoqE$[iG^2&#SPp!+_)iRrjUBm&`!e@]b.d^iP2eiVIQgQSWJa]2Ik^mQMPJDO?q?7"ONnK*4$n*jG"/pK*bUBHWoM#\YQ1D1a[t3_s8N"$[!)'ifH Z.DAaiX7e_Ub`\l2a!Jnk0<D@*g/\!,b)s=S:!2odJkf!B_c8(V"]b:E+>'!Tl]1OpfsO]jdcX?PbXMN4#_DE=,V<]kWX\ba6#V:GRH,*>BYKS!0ome=EtQ^Q^#[kW]&%e5bkeSY:p&'=J+EW=iRQl%3# Ar36ir:$M0tNsm3O;i0LSj,@JcK@KQ5F$#?0;p N817&,m^s7aMrdbsCph_d\pEqLjrJ$\73G`Z_janham:U)L\f1O;^-= rS0pMF57Y-fXA$,-rp01<PLIpiQ;h``1rlTF.)t#Cf8*:Nb<#kTYfM..W&r<`pa>>)B?%3H`VmpcV^>TXRi9]mbnb5Z7mR=H_CbK[:aAbaNpJ2n\M40n>nOe' XG/Wk!-'+MU"d-:?kQYh0it<#n):+ Q+km?m1kCs,^Ui2\WlA*#ODMPfKHEG]("XQR)?Ohc4YPr?t?_>aP>T<hZpT,ha0`KB LK2eefW.C?i1_ek\NdA`(RpAM+Aji(3"aa\)9ttWk4_;(_OB/P_clEc:rcX99REgNR((+!q_WmIgV#__k<\1DLo3R+L>Fgo)c>`Q;jokC1t=Qq%#&=\6kp/sA8+"MrD>apNL%`Y@; ZLsPb4_"FkgoQ8*kNfU(l[8$= "er0G1Fd'B:AZfAlo$@$O\Gmnjm$P$=f.Y5Cep(jc1\:5@?9pnn9MmqSoN&WQ.L!5<c7SH30Ar)'jj;EAAZHOcNpF3IPk7a>FsR 3Wa#E!<LBBoml'A5LJq6MI0 N]E<8[LN>7_fD+mq?OK%#=JUaH0)BE&;]Bs780&ptA YMLt_ptb\8f)/AM of6QC?#hmUEem4MR"IE]0:CT]s5o[OZ$soO!:7I+!LAeCGH&?00pMA/Et)ip8&[%@Pa&^?a'F,*DEe:=i9)UlD] OH@+55;U_%VAPCQkVGk5;7' +4^W.=OP2SEB@?(.Bk)ii:+&^LB9cKgj8Btg8b@=B5K5idP;n%C;N)*:^'H_9aHLmU":r&d Ff_OWB5/g;M4L@X:D/2JNE0dAj"Ceg-WQ]*7I:D?BW+#?_FoSUs*9hCUWe`lK9P^fP KGGI%)"sNAQG-Xr:op<pp%(p[geW0Yot\+7e`AS3#]<I0kF=WD*H:DRP4C8 C*T7[/O'T4+#6f*=7AHC&@?RG;[]_i4)4rt&W?Gq[F>bQ7IO3^#GY\Xs@+:0qKBI2+isSbG+W7O8dm%7hbllcY sA(d]Q:io--%h*4Ge$cAgr`6bh0Z8siL`>Kb=BO_*&ld;k%B+5d@AlW_DBI" <':R#<K?^rEA6_mOk]gZ>Qci-7Mis#?=D#9S5^jn]EHXgp*H_HALM4!&L)N.IKDrXkQbNTYV)LaJot?O6htE%^OE+mIrGUKKGXL:R7Ji:g\UT(*dMpVf\:a0co7H2"6qUnb0o=.B3rI:@pKXMA+_UHaMp^>*>Rmt9m]La!GGAP%0,"%MEF\JXr<%n^OH!c_BdM?NOq[DKqdBL_WC'$D`\qa["]D'c_[AB9Q\AO]c4ad7P-_U"paLAQ#L"_"\-U5b4HnsjOsV8ARl4fi&q=q.(JO:iVZ!8sle$0D&_Y'dG/oO>\R>t4-?kUmH2- =N(;="ShBU9hGEVK P'b/T4-9:`'`cT2'_jTU(,)`p"=@)8"qg4C2hh"A*'3nJJ0]V*89-4t[SPOrkbN?KEJ&<mIhUm9BT1$5#UNnGV#&VjL\;c/%heI6 ASV@*#"f*mWfN.PAT^m$fIYl>#4k3pUV=irI&8gAt]`4iM`r>A`3LiIA'E`'V<^!3mRn$sA*Ci.ah<V0&jLRp6DB0/_?A!QEGs`pkO']5@>to%Nd8rn<kG?\L?Yd&n3k0?_@gLKE@=2`<YIs>*gast/>8)GANspk69PoA5G&>;:9!,SO"0OMa8r`Vbl9B+M>!>1!f"+:9-ctYqdg1fW0d(_#/te4N/b%*DZ%b1OU9sr)G9Z9eGT*aMKiTGY65&8*N35siCZ=:W1GRK<Hpp'G<6!WU)9p`_d&Qf^q,-&8@dBhtI[Y].2eEeVCtijHCiB$Fh"pZK06*>7HmAXCUF*_`S4g 6Y43V>rf:rAEV<0[/,UZ\q5?E20A_OZ25!9T!@5 lm4S"[NjK lC:[(P?V/if]#;Ie^k7gdO$mTDH.m4[5>YIi$hgA#*!]k\rO1U5"J`$N1''Y(Kjdj>Za8.12gsSMk)XY99k8_f1GYUFfn!--Z'0I$hLUKQA_t@W@Un%C;NrqX;@%M"DZ(ZV3UB'B<#Y@,$.OZaKAsmQb]^Qep+OCC:Tj-<q<N\;ACo2Y9P9 /BLs>.W?P`Naoo\W&9T2IL$BH\*W_%Oo:G=Jlr:fiW+S^PhWmSog;i&lO0A0<M=D&D3>9jhl69Fb_,Ghn5TP^4Uh$i"%;Fa<D %`[A]b&8JM9hAU)-mN=f)=qbKYi*h";s6D\]&<a7#i>)P;>TPj;W#r\%=:H\q`*A)/EZ=eZ Y?'E75_`*pL6)H6#ed&3\r:Ug1t*E eT-_$<e!%E\_ oD^:C#kCm>IOsA8!#$b5m$(O$bO$(6kWG@\Y5jl4R-98lt\Y\[tA)IJ a`ALi%)Q*%j,!tWYi3[oSc+HO6oZ>;a>BH&[@=kh(g)?1%s36gf2;7DcC\9)n/([6BQIOB8UFV;K2Ad%8E+6MgNeCff4G3?cFN?-_joN,$<=X+m%YsA;OU8%?/.Ub$fFtQ:(AN9m70K2XEL%[XA-L0Q)>4(OIWAp]qO[cqL>N9&X&qk]]&)?r&UGZPQfj4["I,1Z#QPq\p%_J 2b'nn@p[<1M9K@Tc!<3D,ESNOYoK<+gV\<(ADKc#Z+:MJs8hj_=ae/2m5S5.9<#$hbTNo"^G6=]e&2J3F]$=hS;\Q"]Akt4hj+MlcfdCWL64MR@-^oj"HY=,FeRtbD\[S0P:fo 0R3O t<UkS;dkUN:h8+c`n^NmGXq/ NY@f>"*#k#&aq.5bbOf8Lfq\f^=[6AN)&oXctr\mNAJ.dt\F7a>GV pnj2+.Br\&:0:_S+Xr7IQ`bU?Vf[:<Qrqrp9F4j`^iI7.jllR-'+s7t!Qa,?!1V.&L 4'0<CA`WPVgeW.H9Kj+VrTPZ*? OLFdaE oGn@d;T]DN0cjaX^FiP8I\/OhF>asH.!W6`<_(?BUIGe014HDKZnIDsY/K6`hq1jA["gY^DH02R7#cXmWYh!s^_ <TVYPn;AA7?XVq[mA.tEb(5P+VY?]G<W0T]*C,mNL<]Z@FLmTn`p,mjh8l9">A?@E44Z.cEr*b;cgY4.FRT%28's"b/@6,7-c1.kHnb2$ZjHd'F#E-ir?g/Zf\_#AdeSl#0YD4C##4Gj>$D#dbF9;n/Q)a&cNlM;]&=Yk6k(DQk(=4@'RNh+=*e+kj1AcpC%N8=r2;G+<So 63NJON+Q*aX-+)PL!0%k(:j@.5n(/)2o][O]45X8-Ai_NQISKY$(&r!3:5MM6e"8tED@6FADKQP+JB!oFsAZ@D"39`glmmmR:UW@'8"[QH/g4tr'Uep[+Hg$l*,8,ZLn)s#I(3WPLa.1j(3\_DKW!\BIj#+1N[GAk'KZl0f#(cc=)?9Xc^FG*h[516XRZ3-bpie-0>$=9,4J$0XL!6D0)'Ob"dgmP[20BtQp>aB7D+-B\%4P%\_9Uc:bimEB4od&b!@7k@V\UXltEi<G&O0s!,(6/cb#+#:4et>s6.R,&'; U(]P>&XCp-;XQ\-cU5]9&n)qKZpfC0jEA^++9MA@%LEqS/7Es`Jco=Kf@,Xi.4_p-j+=5eqP\C#qp'rKebkWK6ij!b?V=4-dr#dgXF`9qYWA.nsn)Cf1/0Ag;VC<m6E*i )_)+X:Er\=dg$;L8m +WECs%3=O[+hH'h"Q>>e>E%m27a1"Q.#ng['MR+o;03mp_%#9QlAGKak/A/"Cf+5,Ic)+!*IA,h&jG9(A8"[YMVMCO6m)? V/hN]_c1BkFTF3Sso7pGQ19;m>iCqXEr8:Z@6!eiepA.8K^h2_?Q5@r_8H.5)*d_gH;41/__#gnT8%KE+dqqV cpKtJIF C9^Maq*,]P=Ct/Z-c&E^;M%rlA1"t8Ji42gR\c*EoR)J9.6?e3]_^G+K$:)[6!<Vro&s^H:n`j262HXj"Jp__)=)D N'.jE\A12ae1Z< #EZB41U-%Jg7t3,*h#"=iRo@sC^je%&h8g$BdL'K1L3 5D9.Og5h=&#:a&2q$OSNY>Rn>9\;O7(`8)jBj[+4>AH*Ei@fUD^A;gbla\d7MaQtH#Q"`qF:"04oiKV=^Q?PEI%9eq$7"-2pMH3<\X5L5LfhiojbbZWd?#7m4VESC&=K=5,6Zje@e(58Tl?mmh;Y)T%EPk1r/`H4j%.\p0s%X!Lp2m:L$7KO:B4F/qi0[Wp!O_lO$^*k-lY@QfIDV)sWY*5aD.&ctt)=l-s-l4KTHGR]<qb!T=.8%IBdBT85(krsg/BffhOHDkCM9[GBo6]0q(:eO@&<a$gVYX.HFn\o&ZS>FM?g?P3s"o2[lh[/Y_!K3gIUTiKfQ5^!pX`md#$hL*/S3=hVT/B(P^%8&l7l"'hprAqWCl]c[O=.2#8oJc#A4]F:%\_0K,>1MUd4=;I9k2/Dg.Fo3AJ\q"JZs%XdL7UXGPNmSO![L7acm_XG3cLP886lr]p0N]dI99IKZDEHU9:oMAj&Q/NH+3,28S`g<>RDo\CtZsGaF.m&d,H>*aA`l/.q6d3T3[r(Zi_EoVf?q"UfN\;S7n,Fm4es"OkbE3X71]T tMn(/iQEP>EBM'M@8pa2f`>@VODBO&66T>.3F;^2P?7B%!V%R3#1n$>a,PC5.s'me%T$igaenhZ/';-o&YA+7g]'?9R0 HP)q`g&.N"$%3a0d^B01<O23R"iY91[X*?@7V4`B4_kMCSqjHLDfK#hgMrkVqMh=fWP"" ak5729trq-Pr+/H :ohn_13aM'd52_=$U&()eda3^^8[e-rD[+]^t%<Ge6IX/AD^<;C%@]!ZHo7L+@qd6=+:-fK<:?8cS>.p*oAV*A#_9D2iY.Y:n#kT7<Pp8rWFgP1Ib@]V:BbW:!PT$q$I0a+g&R0UT9D_J_?/A;_0!9Uo,Tca04-c26e1.>N?XMp%6(HC@??ABt^H$%ABY(nZ!<"'Y#!$qC9>mr9/3fdl,8rl[ rD_fBHJ8?oKsd\3hbU7*dB7g:RHIg5lO(/Q?m1&Pjh#B_^i?ZC!3+W6O/PE$ZKKbnVHed4A9aePnRZ4_X02CShsUb`4W7CK4iB0,!2iE2(1 gHgQ(JAAn25(1T/g8d*I+*lY5YG?:.0j[5iUAjmA5>\U"&Y%>A47N8,M\)4B(iobO%XGHK^Sp$:o,BtCTsOp?%cnFK4Z'D-f'4&g;5r>GB1)HApnC?DOCYj*eF]N]1Grg[3+LTKZEj*3S,d]MUsrX+U>EEDJ"%K8lPT\hWM\VDa# 2m&VY&SMB)L2Ot0>2P)Mt-j,UYn"ei>WE%g30n*I@@Y@L.P/'&t">8Cp1',b4*h0pXQ-TQ[_!m>P&>H,<b30ASG88QGojiiZ>Z8V;-[OMTS.:O\+0<L"c)$$Rclt,Q@TWq,AmN=j1rsRmif]G^660B.dm$k$:0EPQnYD"Ag+7M4NfiS[W5F=qPM?It5sChA%g$j$@Ye]CIGBUg?qI+Fa/B(j>ipF%P3m]#k?%IJADme'c<9Li(0rHN76C&pg1kA7!G-,.+83dAE*MN1e57FCNkkN0Y"J69C\k_88)+NC`Al_o[G?XQ1VAiMS!0.]*39J&P^+:D"4VUN)A\Fg-0TpC6j))C2\>;/gP%;C_%NTk^Q^2EJ7Pod8Ia/758r)aF!V'i%Kb)MGGg-Zd#<QFIKOVi0o!q7e6-$Sig<IB-dd8e,7qJ23/`H:@hi(*7X@NPi+N W[pqI`XKX:I-1k^[eC*SREh1'*:ZrZp^b*?6D!C;L#+-Y\A#Rl6ab8Pq?oP)&B25SKYJAtC4=)X2ETM[)J5E1*)+j,-fBKHAH!Ym0ZncnMOHt@<oQVZ!8Xb3J9ESs?4$8B?:Ad*>.HHc6^h/^2nE #<P[*md@R,5:>WQDEKkJmP/7AE'pT?RMRN(>?jId//^M8\D5A-rDDNqn9m=Ok^%CSZ1V^6SZ<9=Wa?B_Q9>lJ#isoZ5-aS-BOdILmhWf*cih9fqn4n)/9V-le Uo-'=@Y%>p1qcQPPM63TP^nQ iZpQM;6kfIl&o[6_MWA$I3*V&nS.tt',OLKtnrCS7Lf.'p Gb1W3RJ[V]7^e8UV_T)_d\/d f+`a6t&dTjV,AC*c1E\[f(FM?B4[3IAWIH]=K;n&rK5_Ts7.T->+;2QEL^^Of`[mY<dVYA"?KmJtjm[YU[+M'NP9UcL=*P7d8km\Sjod4A>3\Gm<Z&F3<+Qi7$`0DaIVafL3a^8gbs+m]-FBseiZZlApU-Qcaj1DkEm&:/d(cLo/+H6nVcH=RQS8"C>o)kRD?`hFU:XkOL."K:a)<-qK+e3^`32^7^Ah>-V.?]07A&m['DG7Ssl<ApJo?6cmc^^!X'=+c(VH.R'XnNQD7/(/ZdkDcL=cqkX#Qh1]8##SEjcnY9LK@5=lYN91_SOSXA"T)/9B?eU8 PS8Fg`+#SpOLZ2SAR(]/IF'kM=4#0<HR7i54\@^\+JGSM/PO,dT:pe*+(C!%r^Vp._CSSd,R!2pVe^*t`@p[[Vk,cD=Io?rA>HD97<>@rPA^$fE;st ;UK1]8)<,qSAOS(jtr!sh&0MC0Bp8:dMq)7d<G;mJ&to"t"g;%)M'2dPe!)*2^mE-^AZK#Q&d!.R(LJW.^Q43d9e[O(^-G$oJAJL2%^4p>7tAO< &$=)]3r"#,XiA8T49/[C5?md_+Z9do<;Lb8s&4U5_PaJtN.,jVn^P$)<'q8QE.8V=r90QcNm@q%\kAIN!E^kCF*B0+'qMf'2>Ah(/^IkHc]fa"`JAS^$$fRX&o813E;hm'U-CS?LR54dTU82 %'^_M<d/Y3tgMl!NdS&&&Sp#?_6pU=I,/Uq8EYoCpF*;Z5N8S_d:Fomj9%E72fo@%X%S_2 1*M1q3*ClM2@3,OZE9$'(N[?tZ^7ClN`%]t-k$[f"#ZW/6DC$WF-&M6)^7[0?bi/!L Tgel;P APkH'R_snZ#YeQ=OD<X8?*+hoG1[,h4%T<'s/tF^Do-0++JA-0J'\0##="sbr]@(JLEHZ6n="m!kT!j4ebJrM3U=mVA.k;#$oD6s"E=Jc0ag19`+P@Set#o3<\BkoI@V+`+#^9NFs"i+Hp)r%U8@:%?9Zr;$kO*<l=%?,fE!8k3X#*aaod&4)O/_`l6.ec5`@O^&!%PD+-o%#'4NbD%rQOV$_;T?@\79rerL@q,V/s6M,AA</SNkg@T./[gb]GoD=Uj*/_1[U^B5d+PL$H,LC6O0Bjq7#ki<<Zjd3/I_pj2^h=<_Wq.)W[<m;i5"To[7!MJ7[Y?=2&;@`fCMM+^*T%dLUHqd1g+0;f>sNOMghCH'tQci%$WPfA,Tjkob\\,5=qAQ#&*#,h`.jDlqi&qXS#e%94D_Tfl&^R=:0he\FO!!ZLX!=d&,8oK64Ab*rT=9IQ.lHJ-gPb<D2lI27,OT(jY+<OG"C$!A=?1Ss*,,fp"=^#aT:BfY>\-K'njG7W$`moQnl'UsIlA7Y>h3[$.50@m\UFFAbKPekPsUg2?A0*@-cRT=mP7TDER0\1gj+WAQ`i\Ts3Z*c1?;jqQ"CQ?^L4=;./Wdf[`cEsFdr6=0QD a18&gs"AW7"nh$AH08?M:NkAGRYL=q_6".6[2Q14nKtMpP'C2I^8/OR!JfrU+'#q[*O3M4L986<pEkr $harIWNoA5\9-pb2@$]8<%7mMkkZ< &\rT3';I<R2 a]YsDieV,`GB#@tSkVA9CS\KAU?%p,\cTRk 9FOAahlL^XpBb$51CT]4'4sBbGt[`VBda5FPg`O!AP`H6:?aFhM2t=0J_'>/%E< Ao8'5X8 O[&@L._>$ZYe1PPY9-7C2# =YUqm+;/5p2_Ann]N-lL*l:tX6AjBiDc`e%!g4;SNaV)>99N!?(KPQ0Q:,]qL>;,.`EUo<&a$=PpGhXOm)t _&;8#HfSRMR? />clW,HkdXYVdjr`:9k=<[WZ7EJ^2l$\=`lM%+_bAn<q9]\>d[?9>jn_n8RL6kpI=kCj6Qg_!6$;,27AAe#bV>$3gXJXD`>G&VB$#H9A lhGF-[4.2?-+;VV02.1c%2Ki3;W[I2>qa0J4WM`K$;[X73<j&dWeZ&sY\bc0DL3h6Nn X9t<aC=Z:tH,A:S^$?cR!(+Hs*)W41qLZ[N$KHetJD<cHXYCZ#gY`1<UeW4(4(CBNKT?H//F.)p)<G"<5gt<br,fBk,XE`7:TQ-A%d65.c-kUq4YA!LN,FBic$fa:NPS',lg):<8EQ7T`X<JBrHp4F1'U5Al5F_[8;MMl:Z9;]`4c]e GaAi e9cMc<<Do__t3cPDb0A%Lee)*@"c[,I3;BP-Mbi\SN;5.MF4.cD>`flB,t;e6GRh)NXkqRt*Z>f$fN%_o&6T@0QjL+8R1O)m?!>YI^K3tWc95Y\;5S*9?Qj>]h._Zs^EQTJk;A?YA^Q,c81pA2Kb C<*dEQ@PRtlj\A,l>W>GBA^=D/<9jZLV8pB^Qe8S#BiklO0EQdM]Y8Pq1^M1;rmMHLUP\$ Xbodoa%^'9XkE;MmRtT;!W/e/;`^&')H.sXQBQ*d<Wc>%EKgop`o!(mi.EsCk0+lONOnlM+8?W't^k)L\==d=l[P5GYAqgPS7TX^C2B:p8\6B9sZQh?j7jrTk[q@!$o/G&n@5E>^7&<U8&c; ^3B;n?,+Ea?sfTB_iD8%Ers@>%A=-h_Fpm&`\/)3?GSTBWjA/6W9p3bf5<A(O% g5ctVrEbd?K:=G'EpI"Zb,-o0/A;?q+AqRN\&^Zn)Z,ti#\5t'D_;NSt,Gd.EnRj0%JIbAY%fMmA_I?B04#>Pm)Wj 2M>5K(<gqi0/Mc9kg=5!aMcd\GkTA^1n.DBj;0DiY>'Y.V"rYkNNDVr?!G;qES[Q7)&_te dYVBJL^LUrQl"25['"`GQ[[k2>I02O^@0sOtNq#Y1:T__V('?=WI_0&TOOBe8f\Qn42^n)?8-YH7DEUq;lLLZoUh@ih'Og:-A"WAK6S8,'/[5/B TlH,%,dO@; A61b85dp[a*F-70:9d`pih`]V:_XcH\P)t k67:f)85Yh6C,pXq>#aC61*5r(agq4K=(,2btc 3CVe:>tKp&mp_;<8KCoG-I1-MgYfDArQRN@1`ds50<AFW70S;lZ:Ger$V43 Brg(]>@g_b:M\<?`,^@n6_1>!?(4U7AHQ3'LU\=l?CG$-,VU\ii_oUnOGSY;f%[mFB]G+e&q/P*V]h!abF`R?;DLen/K;&#e/@V>qZ=cK0ja4KAZ&WlmdCDeV)BA[Z?=4SmqV&lC\%g/6kR!!H)'k<(Sl33W')p_5ko_<OmtFT]%eF=C;lUEJp4NW;BI& A=&cXfbcXW(@XtAbGH8< ;Pfnc&o25si^!jHl+`XO(pUGK>,=q&nS7J7F.U[Phh+4f I$C'6FNtAn[@-&p"Lp(!q(r1FJYc$Zg!9FE.e0JnY"blEYo;r:'Asf(P63)8]7@!o &"?dVC\$n8@^N4GVL K6!:'E(GH E8#okq*n7>,kD%arjH:jgt@p_&6+pTO7;*=01q] Zd@D\\DN@/G3-<[Zp]#">q40K#E@LH/I(3ZQb!NA4cO0B'@+D#@@9naEr1EGW>/4bBj.`lablik#;?\Rc+":=$?MoF5Acg(TDi^ s#)R'lTA>89e.bmM;jKbJk5A(RRJN*i(`d&)5]$VcQos1/#2phBoXB_&VID` _+$V.@8AA`k@Ank9)V36/O.3Q1ikgAl$TZQl5X 83(?dTPs?F!Mo;9L?AX`Jbm[s*2bb`G45<-NM$Uc/ 'rV0!gHW7Bdb`2."U?5`[Zp%Y29@F[Qn_s&nnqKI3o@UH9:hVoH?/+eF(jk')AGn%F1dp/PA 1pstn8fRi:^AL^9sF-!")holtVOrB3f2p6^LEcG?!gmdh9tP<tt5ARprEeQmgB481HkU7i sJ?6+n^DtH1dJ!m8g1rkKCAIqEj$Nt8HnD<7k;]\^M(`0;55dqE[ALIqk"C\<XobsWsNBn (?LX-/6D(=sT+K_3fAi1/kn1&TX<d27G<:htfRBI9`.2<fmRVPF#h:Q11&/T n7fIPA6.gTlXONt'[KfT=MnG2(fV8Q`@KVMabk1t-nX`HJ(V+)#%%4Wo&^l\HD3dN8E^``; G0DpaRp0; fO@SqPHeUDdL34o"f_.&(\9YX*`)o3XtAYi5E&T?<]Y&S(`2=+ %f9Q4O%r*f\L%V.s8fc%W!iY1Q\8[PT.`nF#QO<D1,<]Ac&Q[P](:Qs..\E')<>\`YU0qc>_!$""8^)Ebf!dH#D74(H6K"e%+hNJIfqCh/3BYAPQ\Wj`-AI28K:3Y2S[]Y4B#3_N)X8C I.h!P)f84RgSPCq5B3^J@Y^E.WnAC\sFJ;!E!/bEhsFFSb^JsGAA7E;&%P]c+P:1N3`X5?:A,]%L1IPV]H@Lclptin_V&<fbHPR4O6JV>%3YCo_#q`k,*ZRgL PJ[UWm;C8gkl?c-N(qRHO/pSq>ZOjA8&'bm5e?Eh]9j-slrO.(WA0>"?pMKO`$3MdSGlj_kr4#0<#Mjd_bff'0]O?'gC-dAFK2YKrA%MUDn /=g>K%$mIpkWb-oTWY33@42n(*PNQ:rcKA./AOFI)o '-12j,gQj_&fAH42)VeIR#"]>^B::]DQgZDLTG_9s#`\4\s[BH6gM(k: +2n2QFZ1!clKpAjG7hLn.F$XE^L_SVO*bU<XM*\W&;-DXMjXaaU+*Og'-)=m5nH45B,@q'\..8E!E#;r4'Z@Sln-[[Am<.:CHB00Fa(0G1K(@dH:2tUNqGHpK$W(P- TgRXh*49m.=hAFsq/gS"4[bio !A]C:7(+$[bo,gY@8jQ-&=]3ohbJl#Q1e4#4<$Sd5Q$E_<sXD3glOm,WV]+j,%p4$G8m:Ofk%UmNdUk\6se0lqt?e19UAHb:4Chc;S10-UPET]bR'RpIja)8GZS]#95_COp!ec<1jkMS6,&5Q`gJFK@s[[#-*WqVm:Sssi_[7G#Wlb>+t ?[QX:-cgYH]Fk_?:/sKq22<6L!0hnU-m`la2"Se[s3TOG\U1i`>8]*,j+A^l 33gKkB,l)a );aoOlC<#nf?hf)6g[58_'A(N`> t2f2/X]ZAS6JhqllB!h2"Qe483 !ne;)2$:jbp0G0gC\t3/&b2nRoa;`lW@p']OIIBK&Y)'l@$I2kDEMD:*@:M* )tCf ^:JUa+9,r+FG<;;R*klWW=7O?J2"(4>UUJ:=ismVp!o!.Z6_4aM7\op$0YAK\34V-LR*2ISSKr*+Z/j^L4c!'>%mW%QU"PVbHEcE^=A@B:#L3g)N'e9*m]B8T%m#p[hCQO"k`8,B^j4&Z&<nX*RA#^HOR'M=,53`*RR,Z[,.MThq8BFpCA(sBh5*JOC*(9`_2-$QLUdc$WZP%&`!dg]),$s>qHa-EVlGbn,^J&hG9'9AI=Y3P$tE_4AW4Y^T.p@<9d;9*658d$aS'5f3lXJ'3!_U3M`8JBC-G(FeeG[Od%he_"%Zo(,qo(c33 .m;:psTHUiPU;^lGUshP%5%,l?(]Mff;n=[1Wgb^Jf6Q,<i.M"GO#@k'Op@GlX#>jIGqAGSTVHpWL5bLj'.sf.-UBjlJKfqd_d4rKEL,i2\/Xciq_f>44PRpROh<#^&H[$(RYW*^,/Ol I;l^9&fj<Llr`)PF4MGeQX0Q,rP]Sqo!k@5`+N]i'NE&kV@WE.KMn<m>'DtNl[(CdED]'QdET6dAei#G=#f,sqR@AQT-&1Pc)]Q_O&6#i7$iP@>lFZ4],&-MfTCg"*'`Rq\Hh5i ,L#+6$:V6SW[Tsi^5iG-t3Bf^FahQCOd=q*[R45bc=?GfJMY[cR"R"j9,I=EK;bh:l/^S2b=[8+JK;tZp0p+V%:D<B,JVXfo6Wo5LQDls<%5^fJ5Vmqi^\,5X224ZK\%:;3H`8a^1&-Ao>/Ck,gN'E,_%DkBe<m>g)a$nf!!-2=! >d7j=:l\pIc!A'I$p/]c"n<L/NE-1Qo4Z:@ST1b6)dQG=NUfIq-,db`a^GSMm"._AY9GS?i0*mI0gOdfr`lX?Z^ZF[1-&l:5EV.!>P/),.nt@/,7;+KVsRO-acIj`g;m[^#BkIZq_?TA990PGc\.ACkK/orpm:'/jT9[jn=L8C^-f>DhN?YX:AF&q`t/)=g?2[Y%A-2+0:Z`Qo`fH81%/d[s9oqo\P)=Fh`Wr:ANZ$1\@RYHcJ<:'He lQsoo]rJONQJ"3(f\YqO@HF!(=<Um[kImM3-!U>U*]\1Y9a''A;,IIPeHPFJ%2=*1FsmnZ[ANmVXNPRgJ]B3=g)37Grhd_#mF15;O&8<#?(W96;ImlG6EaI pY8AASA02NtR^I!7^f9k#.=R=cV`-,_&QqIFaI%oTn7an-!pO;)N >JTTeO.)6'C"AoK9RnLJ@+hHRj=[Nb!(JY4*rrE'R0)qSWPb?C;Rl(F9l?7:XL[/DNS#+QI^B1Z7b);nIVsoOl9CAh-d-- \\PIN!S*>-JL/&-RGcC1/ aU([@nG*4AN<(.7Di6cLgX4qq\D?M6.@Fmod%de_DD)&'9-_m&?nrGVEFnk.M)UW$i%kPAKUZ%!^+,2@b'Fk?4skJGKNdUgZdokFE" -7']_m. YO>beJ?g[Y#A5ARiT(U.KVe4;<E#\EbO!iG`bakX:qjjD"p5Q0?4-\e!(2QZ>:QBgOM2^OZ(GK# li9G+rD>P*5o,H/O1I&+jtt\Hl:Ogn4p@@`-"Q/jcmS_at&C8lp-c`DMh!4JXYN$XKYP(Z#%gHI EV$qpVP_Q/Q:#5j\=bi]bbPUH6]sV::AK)HT^O)P P"+AR+S1OTDd$[Dl^!]if4?&HP ITD;-/KhdmBaANA#$Ll4<&rOIA#[H583h$0C##K"tCp'n^_>s4=lrM\5SED,/AF^Gn#Q,P38AD+([Ka);gF43.fV#2iYG]9m,Rn$t[;<4kC:7DAf,R*bZQE P;5MqT$M?_HfD9@];\?U5qsqL8-88l6d<C 0H7bW,,^c[#3;-=s(H-"],TQO?%<`L1Z pXPs$%Cs\-$'BX!PC)16#Qq_WDTaBN5F"U[;(SB,6`rH6o`9<]$K.>_8Y+ntTHYEc21Cdaa@Ak=]3$2?CN8Y)qY;H?XY p+*;IUdr]/5^P0r\_335Ek6K7Ftb$?Zbht\C9[<4)^5]HpA$T]DKTes\6aiW9S+^+LnGOqBN,Wg=L7pC:;h@o5WU`lZ^s]aNsHJ2$n-?LF5.a.]4,r45grfiGJM:>[c?PqFrm:C6*gC4[MB244"jJ=>KV*h<pDlGdMJ2Pc6rS-'H9I.0@VAB[eqgq^+VN2&=Y2&UOn>@IAR:sA!poW,4m r.VEq5lgo](gE3$>d\r<_.U[WQ4[OmeY2jZYaF!2TDolY'\K;S_!L><t312rDS>Y9@p:D2kGjCdA\IA_I##qQ:Vmf:dS?O?=][Lh?OQ50S*nTHOoq%co`Eg$&7<=0f^J\24O@[Wl%p8P,E&oQ+S9Z^m7k.`Hpr ]cCLnZk<c<-iSdIeBg7c;OkIf);j*i$nTV:i^DYhQULG5#UF8%TYHl=2ACj-mkW_$J?@#0B#-q>S+V:&NHM(drJmnra+7SHMDS FVt=aB$XD% HqbAg]"BgL*!lGngo-!DW qI)=A[(jM:YV+jsZ!/Pd>d,6&'^$cDn(U)lDLN\V(@Js+kDN0DcRR\%(@:o32!p#PP6dDP!],@[>N7A VY[eOWZ*@^lWXZm)*+P[B]1+%oY1h[hma#L@#_LJT5>e[Y[&)RH7D^()tHOMCQ-p-k>f-XppYP7a2E>9,b4$Y3N1CFWr'He.?;DDHNqAO83oNqlFR@A[?HJM>4r(QJKfM;Ma-++]'D<^G.E+A;Y5]eVl>'t?S9%-)`3LDd-g''5n<t.aR6SJlSt'aR6c?;NA`,bobV-tJt4hm7sA#'p`0[cMiHbNp ]+g'oa4lTED.MH5#6m=0(,[#Ah<>UQa^`#a'HA;d;:Nnl1p+SJ"(c !$27gl@pHI(gSSa0*9&ggk6BJj^o\!oV(h>oSbg%/BHeO-mQc#q/G?cGdN(T/1&>JML>@Fl0=I4)<e$@VPa2U/!1ec9S>'?9pA&\anPs=2+Eo9c7=i\psA?5!5%Zg5,-9n^jsb/cU,N^3LL<e\rMD$+*cZiPHfF<]l_?/pr>(hi #9lYqB,ma6+F]j+jtnHme!nd!'i-- >eBc/8nsP,PmfHT2ROo'dMQJp%6j]RdBfS:^IEY'b,*PqV!Dg"4($Y:^Pc"Ta!(k5SR[YS#Fr6JpGWALb:JGc__UGiAeXIoYAE`7( :YX?cH/Mt"c-WXD '@Wc:$s^Bod0RiiQqI4@ANe@aY]:+0XHq*c(p=sW*%tP'=K##Zo>CmpFq8H S3^L4`<0^mFrnM&[[`p:+38A*s1/CT%GU'qQnsTs7B_2@Ab`NNa:a@9A<XA0_NVQ*n564;f.PTA`DhU_*&,N4^^70s%ptqQ8=Bc9/j+=(pZlf31m2UTL8'M:#d\K7aA22tH&ICct:YpIW'`Cq>atSl(BMNC<,914O<14R(V*W[VCsJfjVJ;4<<_f@`9bIV&LBHY]RN2T nIVn-7_Re;1OkUg+XUoY8NsK26]>c%eaq*C@'>K4JS9Q@^`Ik!aso]nLZ05%(dtNH3t<6Z/ZLP@Vm911nMb't,d,.\\4Iq9[(tUT\/:[jO7PQ1(p>%/ Z2q8][fT0^:dq]J8Dndps8(WdVSpi;o+loBSpA<(KW[_B)[S(B3fK\&0eG8_^mOX:@_MiD%%YTeDg"M0+#e"nZ&o^VLJG'nrU+1K.^c(OZj8c^IH;%5?A';=sO%fYJ#mkknh`O\.`&nO]g"-^1%d7!;EBsje\tgXg@ 1LbF7(B)H<K?`$r=#j"F(0rM6ga`%#Q`P>ndn)UAU-SpX?.IVRBm)hC5^3XSJQMYo+L9f%QkYrg;:JBrkrB@op(;oXJj03j1[:'@VIN*5)*#&O#T\nA/-UGM-)_AVo/m4N,U0lg>cTBs"X*AKp1L7qfZ3(Q/7N2B5kb1!B_.*3^1cq#]Z'^r>JcR(Toc]XZ6l+6@&A_<?LFrPo^S/L1j#/IX@fbQt<HJ#_oO0)nr.-&Qg=.DS^JG<BAbnUhAdJ'K%)moA,B/>PFjDGs!Xs+V& $=kNhG!d<A.3!jLiphmV2926ifBat#+,&aUR&+*$@"#\d"YNsAVq(C#Aj[A55O9L2f=<-rWfMb<<A\)/tl#3#]IodF3sMjWXBA]I#N4:<^=D09gQ`Rp%h 9X2LlEkgI"Ds#tb8U/S`DJYs4V'$9>e10LY(<3B$L6Ng%,O+1KMe7j]qCD##blsi:D6^hT0L2E/XC1##jJ53>:[m*!<@8smWH`ohme=E<nVb/6aU?ZrM1:_Vo[# sGf8)Ye/5=26D%0o-:V]qfLJK'i:<I#O+jZ6)KEoa+h_`9S^(pX<$A$!p``q-O`UfEt.P#/EN>j QOc4*4[<YH))(9e^8FUbh\\?e/AShNT-r.Z3(g5KZ88CkJE&.?"X84e9\(7J`*9]@(]B/F#Jd_55o0m 0'> S'?Jq000Hj)nS&C-h<Il]`q7F>jpM%OdL"L93iNbhBl]69Oem:CEF4@QoJJaca\+sg'#F:=fgU\e7Uo$11jKI!)&1H,'8EWA+-*eRP2j,-oBCf98A@$6+pnajZo7oaPX:`NCbtfL-<ZDiG`$i@78m\E#8sRD0rLr2aN?)>/G6bo=(o&[V6e<7B=! 5@JO_J`Q.>DT'hVtM8V-OeUSi?MF&]--F*c,kS@&;4e:S_\VRka?EWj+;*aOEtCpgL$r`@fA:i#O\@p`htpaOk@h-4,DU<OjKSIq.Z>LE>%!-0k`DDB,,'^(GhA'^8"$8-kZN5/32%YDANP=eUi\$pB62fL",W%.lSaQTa3.?1"Ye54\9RtZB+l_e%>RT5bE;RcbmS+e%<r))S2t>0 &&eg/UnRGIHB"]6 ZiA(hHW18NSP40lcp.BkhpC\44KA3 G][Jk(YFR]t-c9\17nV;XI?4l_>IsZR3Ko9-WNm7*fV=5i#8FE9f; sq7tdJ9(W-WBbl+s0-F#h>H8K/Z_[B\Y>%5i&VUIT&T<62^%cH6D&r%U]9>0M^OC1\P gd.4?^H/mp[A<i/+72`!Q][M!).hMV9Lg0&Ue RWH:>^TmW<0L4W>1EfDOG:M6r#/+TTi*of>6k5BTlGm[)UIJ"=8]s@s=G9;^!=7?4'KI$"9'R%l`lpGhUBJ]8ncn>D[?'`"fCLit50"Yd^Xt^Q!Xs!>8=j]fn#=Ff9F^b`Q7p*$!)Yk\=hps2(4"sVC"o]k51ro)`1_6[,@<1DnsYa ncRro!mM!?$n5/,?'rnO@gUMmaW:Bj%M<G &6]8^1Vk7\EIS 7.hEOaf!`@JkdTni7VZb/HEI_lP%#`,sJ7bKioQmU-\2An&C)8o1A@#LI?6eXh@c7nXKCbp'l7-6UW0S=UbY[^?K!(A-ss5RcH]8$rnlA?255qQEYR^gSD/`3jh]8:&jre/<#%d1nX7-$mH6AM!2S=dUQ7')cDIshAQmChF#5^<[t$+QXMqGf*5ZS\kMsR"A4+&^\si$6l709m217`F9&_r--k[6\?>bI/2NVWgJ)-W^_#93Fc35fm"M*&H;"HY;A85+eKZQ&o#'%^QUID!nsAm2+IRWJ78+-Unb/<=bpZrO";8mC5$j5q=qcmg<JD/D M"l:IWY#9B-EE4\q0QS]e).[]ap9M7U'a0bPA)$Jdk9eDKA_]C#))`+oI)jl^16eA2-qqGD0Viq5L/40;?5V'kM8sUqbimrjr7$8 *W2A^]\,]4Z+jFG2iSQ*3'ibc8n"Bm@`#<"4MS2N9HZ6:/pd/D*_F2OD"Sp]Q1*84BbMNg/REY+7O^WJLA3r\jF?5?m9?hI](^ 7pfcSO5)nO`,o<C5SG=Qtj r7.^j?8$6a5LF`7-;,lED^KOI,Uq`,7)o9'+eLiZltend`rq&]4YM.QK2hCt/NKUXH<HAU,3LE$9.<Q6I#VV'AcJ4V+l<FQ+`jbSO.<KtM31^V #+LE;hYMe5;ZiL N5]l\.nTDUoP, p/0+KAf-Frf.`9/m4.;fWC0e8*Ak*8Kid=rcLQ/]0#,n&NOi41=(PVU0e,XUWLO2=[gX;[l;s\5DM-/(W'M]1J\79.JtP, 7mEQ@G.=q?40Fe "\.^4q9j67(k%*9He?Jr$Dr4(@LB3)!'(g A<]#/J0TU4io]AkCQC#MI>)WJH`$D?>l+0k<.+-YmXZ(,T6"6h1QA,8>D1p'!(N=!:3&gO:C$9o\>95oW'Q*FC-iK>`IW0:[. 4?FYIM[@%EO;legl" 1F?,GoqD[B5*3NhfAj[a5oOk#dWAq4!qhpi=67X&-N+J9 ia@d.VYOe.M`K@,"""fE2sa]I=-1o$  U88DcaJX,X(FTXOb87#\W1@='4"3#.BsP Qm@s>$I5+cn@>DAn_RB.Q!>[q:p-c_Ebt-Y4leG0)8nOQJ7"5Fb7N(*+)9WtJ1a[=j4A@CJ!T_r/[-!gL[JrT,t@k^iPAX=roY%)G=W:mjl4-rZ7bK+(B[R>6LmlF]]nb6m;".rfrZAHWoZ_bO)b6#?lNc^ 9.[UV+M1Kgap<)9>],RN9(3MF[Z.Ro5a ^bfm,09"iFK 9S37-<=A-2n1Dmrq4rA<B2T-%/GZEMM?Xnr7oC>YbF;LJ++UXR_E[jk`tdmUEaEB\TR`^ZZ5+A0i_?gHjfS^c!t&pHFc73YsNVI<QXs=]J"RF"AZS1%X2k!=7DN`DYr@A*%L@$T>[)_Ut-6'e9U%2N&&r>\HX`'GPo716A8R3C#rN[<2,V_lZ[?QkL4>R>f%EB5_*Y\2Yn2q6K@"7pIlen0cG=dC$hen\dj.ho-0'Ik. c:8(+lT$Agg/`LIt/<2PH3>$oW!Y+DAo1T-"YJf"_`nWT_)-F0-0#TV"\*,/Ai5VT@iTnbAI0ornM+k;QZ7hkX*m=LeIHtLUPD!i=f4E0$h3^C/s+".a0/jgoGb0d/?:ID0jt)T%EL4PLgpqkWU&;d2"]Op#Or@7c#p1r3K&KKUs!3^q:W<rjDEAdjfKj9DBfaGkK]UftriLm@eTU9^YZgAq'&lNr=e>-B3eAfc[A_=nR3lN\hG5![te4+Ealfg517GpXQ*cZs]US@No>\OtkFUXqs`e-7#3TYYX;;p= G`kGU6JJQjAChM9^P+S>qb%ZVL*a5LrMqGjB.h lTo@_H8AlHXl1s_LHZTj6TDPX#KjrO1Ph,rBN* 3 m]dQ(#QU#5s3shF,*rZAW$6Sr9T;4WAQhtZ%3+ r.$%pDG8  <VB>M7AEZ*m'k-3N@(KnjQJ3"A*EF/h/qst?U:Jfjd!)MmP1!#PGL9:J'$sE M.Hf]]Frld-%*HUVWsUrD%?K"F/gXPe!LjmKNSM1tJC$NK*o5Le#ors`6iLUg1=2MaD02aaZH[geljDkU'qc(tg&nL'102,0V>W?pZ<aJ2X7@_D*K4\jmDU! h:iJkSl0bA7`R_l\_W]Z08([5@a"ZA-j3mk[]PMZ`$f3(;^Fr./Ib%d@thJMa3=tcLm"V'R:hkKk 7L`oiNn$U('&*q5ng\&(bA+(XWK=[^kEdd+b`-+/W$:t0-AA\Y#m]ZMdg&-n0l2"W#_hMjBC6fhYP@ATY0H>-CB!:$H\(:dsB@b=$R+"Z_*ZFTDkp"TAD9bs.88&8?BG0oA`/6_9:Xfeo3J+[BYcc&Dk!DAhQn/HO&mEGsZ1A1\%+HmZ8AO6`J T!3:Ggj/R4V"?gW2sXh.2G``LIHD`N5lC8-4X4-9nBoZfAH!;Fg(<LATBWW<iHG N;14)WF<AdA*dQ]%#JSJ-^U9I#h=@k\*X)Ij/>mq!EO<j07jU^?0JMt38[PB:3HH)i+,+V#1,UNOs91c-i4A8*8+ec0KBSee(Ye#;o%&ebPaoR4X*eP#lFiL&e=A',3V>!#i%Gc(1ZE05MaV>"b"OT%F[U?Y<ghXN^:[65iD\*&2VNb!d1(aHr9`c@V5DrKa8\rK^W=t*jhp4 )?g^ McaP"d<m3f0[$1Q<=)LDDH8;& ^X^^?RK#=e)rqV^F^lB2@EDpGi77t=tO)GaAXT$=]`@!!L$VL,A*cA\R'XI_18K3WoC6gfpRcM+RAtYQF T4)!FX^JmrM[AbSE#`gZgMM=Wi^\UR06PK&fegH7NfWAr^3>B.to1!4S!WG#g>I-YU"s9\s*H!RTr]jS0Z)4[9ig)'"brRKb[pb7 7M[k8.B]i.*)oHiFnK/Cb.qr*OkY@jc5>^K8g;gaf;Eb %"#?EZM"6[H,7a+s(XFiP)>dd%(lLHTUK#4pZ]&sJOa,&MRZ!$2oGO&=7Rj7R8\pA/p)0a?d6htHH19G)ej6sGfjWsS2@*1^c"$'0LEI5*!X8CdC%j-99XcPs8X+s7H#H06$*4h\^KfW.U$r#Tb+E<b`OTUS0 ^P;h)/?IGb*fCZn.]LA7A^`C#(h`QHQTVCZM-/)VG:j/^Q]40b!jN!o b;e1=06?jb6eL(kR+en:g..fC.1%9?Qs4>G@Vf6sphpDc:A5]9hkD7`ijZd5^00%_N0B$5,RMN7M>Aa;*Y5.F;rFnK;E'):<U&Ks+Z]5>kMST!r\G=<W.@95ZEM#((]-A;9@-fH9R 'W:7Sf?f/1qO! X:G.*C"kA@<ZF[iV_ZnhI!5-dkP3[E-P`lSQ>^DjsGF>!^\4L8>VY4$VJ\WUpegjJb5ArjLWkJ8@W'a#p(VW%7S*YSI;IH@A\O9)Y(`5jb]F )5S?,I,F$./qc@SFmHfnFf!$bW+erR:4Y99,OB;caB.E:G/B>AnN)jF^75Y)Mh'<<\1PSGUta0&WVn>&c]ShG#qb+)fNmE(tX/13]n!'<J-#*1c^feCND=^TI:"ssoO's8GF.C._rA9(202EWB0*r384ahQi,Y6-hA&g1S_1Gt'X0]'OFbi[cF>l:EM7@M9VX_AT$\[IsHA#NQ+0:gZq'@W"\XP,<*tJKl#E$*0O[M1$ii3;CA.>bT8(1pp4+Z&mlV5lspqsJ)?P0eXGmV%CqZ:P9`KJc9TQJDqa_AqVgGKJQW`\<%>&@"2W+Gg:akVgpl1><:,N[K(d3H[;d$L8)!9tn7 >P,YPND1Ij%bJ""!hm!>VK"AoY8[)gG\@ F1^G[m6=5Y]r$knf'G)e20=.Kd;\c*^*;"Ds*O$K/kVOp%PE33M8C8-3]Fs=HH L](7Xi;BBRDW<`p<&^(IXmlpmT#oQtY>:T[?W`Ze^_' %2.93Mt. $`@c`k=h/nPPf\Gl655MMb//13lm<foXJ 8 +AqqQW_!LBF_,,KLLg@bNOSkK(?YSKPWc:+`1L0l4D49UQKlkCB6MeYp@Y@Bdh P9P"WVA@pn/cd\N&LU^96PA?&FZDsM8$R'YAJi_b$c,_# i2g1+BTg: .%6HA]ZZ,U2J8W'Qn!Y7TF+t $m /5R#RCiRY=,07#S:Z\0Xl$4T\\@>fahEaDQ(+47_f6g)I?ok6C3DmAbbj@Erg&S7[eK\[C2-oTtY<`7AU+?tAllfsA9AL^+5!EU?bD ftpGZD(COq/dchiOg;]F7b2-Y1_mcq"-d^ 4d75YdVN9U%AZV:99,YIPrG'a2-Atnt<q.<&-gC0+1*%F70/$kqf8lH1i"9/dIOtnl8cUEAqkc_\lG6BQFc]p+m8](X)i0:9I=8\lJD\r;5et'3ed&6%$g<[M.kCG[ifSimQ%Qf @OD(jJT/aojR\2_jY\U?TI:IL<$V``i+[O%M7kh58B0p_5QUrB[ ]3C11$<phVV^6Ga>!<_^nER.*g\cp, QW=?8AnA(A+eLrOJ9Ea4UeLi6NAWJJD[Ai$+E?>R*o(WHjq1?"+n?`",]k3kX;'^SeI)]2."\9>EqQo2K?^iG)TmRKp?=Q\DZ"__Pf^MW<KFd6MTqG<VL2*p]I8O=,(T\^hf+-WI6El;9Gr"'ZA"p+?\+k]M8lV.Ddm50qO**ffH4*Q,bkBsTdUT=g[4*pF!\ir.jAN\<9>#&+Zpj=/B<Gj8PaFnMW?AfSmXqKWpU1&O`/A@=O`QX+30>11Wa'Pk[-.:pr_1.L9YfmM2NT/X(6-NEnK'Fl>t\__fN- ;baPoO<4E8tNq8UpS.(W8t[_B]oSl/A:& %(Fbi7t55lf3LigGUo$s.I-_=4,^I;^)$d&92Y$_5McBg<Kdq;UQIs` 8^ssWMa@[580862!#5C?S^T6;1cOOnm#(K<P,jn<H(j_/9$@pZF,hZt]7)RL(V=9;`9paOi7%VW63t0j9T].9=\.4\]ePD1HKGBoq 9/#Kk"QWWcoWk4cC@=on8CK`1sjEE[YIW EE6r9)$>`]bD0npl#ILcRXjMdP<&@H8HQ:%W'!p-b@PjasM$c!tKpg`J-d</W!tLM09@5KD1"*:T"+Ahka;eG>J-1sjS5+cAVplC@Cf^<AqsfQ^rEFgjqd_<o/47_mP"mPLk!>F(k%PSj4/Y6h+!:2pXa#55p?s0)oMCTgq+mZdX*%,g:L)MPG`qi(PmY8V=9:DOa]`H\MeX2BUd%GYRWha;j8kkdDkb!o6%.c!^o=L,U/Pnd[Bm35ED] @N&;,!'_laMA8k44iGQlM?S'F1\a[qAlX:$4@Q/^jMojWh1jTBTF@$SDRlP,%"W7X.-RSkeK*KV;:tDILZ5tQUB!%\P.HA5D>m!q,qVD@r1+lOFE<>n*7D0.F`HHhn0q d_0nFK,1*b^^40GoR@1lSKZV&N3FQ(BDcl^B>3!PHCY *E1bHs*Sr[j=BXR-k/6V0#6_R>VYs:VoaBVCNA5,&r#;c#F@A1$tH/V@4HTFTHA>%IJHFV_=g2_Ue;-b?)pM&0BA`(`h,f.XL8U2<F(IX?UbDDV["!#R'\4QmFA9EP\fkE:qE%^(P+ZnT'P4]22'Q$ @$H+C'4S08@G9A)?HTgXJpX&Yf*GnhAJB"7"f3/2j(NrA:C+i)g:]Ss$ TsfFbZ>CB9Pt#]HNdPKsQ"CXQ6MhQ )poA[s&c F"RZq;i!=DE[Xl2MH"DYV`D8<*UcPWP&i dbA[((MNLT>hFpROb'7W9*&m,`%@"40b>aJMl! 1gD&sDRtAd3I2llc41."H37l5N;$hj,qI.M0KO/:Q3.f\hobc1^e?4CTh/HL]9[A)-c d8OZG J>eR#Y/EIhlP`22ce&C-S>c'f=_m<I"\/ABk$a3Z\LI5Y*S:@0L%>S5m39X&(JL0B?>B`4;1`nR$DhTHFQ=*UdSa3:BA63T/D5-Uho >6iZAH.[.q$jVZslOnD)T,=(''GYSAA]t"M+)H>"k8; U4BWgsni\beh.YDfrY(,LqTUA:K.OlE^Q8f8%Fg_+eZFZfn`XqhQ]?%@,X>,nd.V<$]KLbA1k^[M'?,ZNBrEiS7s4to=(bAJ6;O7C/arKE$qk5>2KkO)ic&hPmV,@!Q"2Xi.rZ-i-tT:t^t,V9%rP8I^/nRIR-H^bKP Un)CRl&BYVMc>Qf?tN]8'`,-j"!["F%"/P5:QcTgZVlMXJ']t2A,Y?(lkdTZHnio,ta4J`QQ-Ro;)0[.=D*qSFa!KUsM n.A[VN3FqG:J7%THcciT20Z$-.Og+It']r7]meY3A$`*)UN;Ep9h3hEULe"i<f:6Q3GCQYP#)U(F> a:'^bR"q-J-1\V>CmA2liB.fQ\.>`oNB!l5Af<[7_;5Veg]JS3MUq.t2j19N[kMZIkodDDhXNNl@Lk['\(\#Is_V%M,li?I]V*EI@\sJQWRe6/QH:k<NH3Zgg^W`Y*@-I^_!DUae3?_^V6S=]\'8*Ehc'0E6qLPgL&4X*!DP\n&Uo94>>9[pf^+[C71lGU<@Vh>5Br&3Ss9&,9M?QXKL0Am&*VJAAs>pIUjNE"-/T'@gFoAt"*d;]qj gU-/lRArHsq]5q =UkR6(Rm'(++,o;3[Oo;WM6U;'$2X)/qY?JG+&1Y7;EGl"E%!rk,:]A@j8*]A!<Utcd(TZ7CkEa6_]lJ@9>3'-rBrKlpBjX[&KS[\@0oKa%/@F aGFpV+Ak1$@"YBk/,e-Fh"S@JP]IX[@ZRCkVb9[_ks`jDFpC26A\>A"lg.q_q/?BVN(PrBgJ.(RG<if(tY#M47G<m&TE>YArD'Sa.1 <kh?VXr')f3&=BXS?SRJH@tbLbb+!V_NE'DT=AAq S9hAOSj?LO$PY#*;+Jt5hW;t%XT@Cga[KtT(*4Y]B 4d=*AA)J5.$V`t+(kccX'KAisn.jsO$d4TY.H*^abrt`&UepA`nK/+CEjDt,FM>UAC]P=_1_Qs6%bm$UgJ)..gWeGilHJSqjhYAd+'8jYZ)[YelNG2%T5F#."W:S; m_Jm`#) E';U(]\\hosFM&ib[@OdZj,mdF-MHs"mI"0]JST6n=e>s^]>*A"P/a)#n+t9,V-aI3Djm(FQ70R4E:g@CJ##3IgOW!qe:hNGW.m`0._f":9&ZmoaYX`e@*eC9isRL^iesY#</Nc55Znl0_/+tVD:9"bo#qrmLf?m!C7KP:3q8P+39sjn !ENR_%]%P4$T)?,6D,PSnpJtC+AE]IVb)+=4Z9KokDLA;]X]``a!Y7gD@O#<YWR?MCQRH?)5++^6fOH(ZcB<FAmNo.][>gjoFR0K?$!\Xl8_11k&;+!%V/QN/;G"g"7]4*BX(.F'#[ET0[b8sO>:A:daV2\OL8nIQ6PVqcVmTFb)qs%$D]-:Am>re,n6>MI,4<W8sYBGhI#KfkloZjZpBXiJ3)^SP_[[`ca8S<MTrf+a9#@;UZG\h6j=o@%1X/8P<([@,B./Vic^#Zjq4\_C#+%_P=]I;R-/S*h16<GPe5,A=<3h"3""+KLG8H*>DZ%;CPf%51m?BcB%"]=snZ9BU9[ X/d8-Vc=tqI&P*pCTrS8=VW2qQ[_o'*'AENb$ac$nTZ^6oMUl>_EH)S(8>Bn6K);0Wr(<Q4-(nR.E@qAn'3m$*4_XB:I15Z4V@%UY5 (MkD4i+HkF&trZ/5)$Y&p8[Z'A5$h">cfhGpI=8& on-C)Re4A%Z9&L*XsAAWH=5:tXD-)<C)ZQb$BZh%Wl< LDp6=U068HIT'3Ced,:M4@Qr>ApKHW;AM5X;dd`R)3<85dG>KD fF+`oDgsgL$knXJn!(`Vs o#5mg=J*@DK<M"'CrspECPY.%t.J0>NeAgTgPEQp[(]me.4H=`:\HnM*j!eg*ZIb+EfU_op"/FWl.i&TI]gU<&aBmh5:/HG7ct`aFABOhS);p$q(M(%<C\X>85[[$X(Ab>=%rAZ^?!>D#kmq[OA;W*^Z*R<XPn^ Ji=k`ZHj6)g`Vpi ^H>#O^Q@]HnV(7T.\@XpomAO!o2fP#nsdcZnIl=%eA*YoA>W?^J+Xt>ZMeAcHLs<gABCAjf9SqT4*[g6j(.^DqC=fecRK32iUcQj^)YSp<MM4H"C1KeAn2r5W`(F_ q=qP#qGKMh2l[K*P k")41NAfM0_7&Pd.c$5['?(kY/_>`D_1JkBtWt>F;06h5#4O[4+p.tC5K)L1D/(0:^d(lmalVL[Elc)cR06B^%J>^s3DhVi^Z<Z6iWL7B`2SPe+q+5]9e2bU&h&2nTag[LV]S9FX:jR8^n%6f5$MTB[bn\sS$3h(5ph,Jce@0lP'hcFhQrChf>o*?C+>T/"J4-6'J%#A(o/?N4*lc5mOfS3N,$F4AfNMj8f)l8p iYFiO@2e"7/nE,GCblomBE7AJ9!p3:AMPme &Y`o_Ork6`XNEMo_otZa2N3h4.+c$!+4dT5C1os+jGG@pom5=sbo+'2TtjigZKr5m/pMP3@/+#%HSt=)SfU\329H^*NA+,J\OAZId;&EP_j'j<#/@a,%r=L'1BPiH+.LgHOA%'%?W+lO"RgJ)e<K=#8?Ybd r>`o.[WPo@$2)GEF1BG5%lZC2N7JCB,L5h!3bIX@AMj5%W2LI%;Zf;fH1`PTIQD'-r@48"V;p$iP3KJ.U!*E!n76L64O(oW7?CV7<8:ZhPPZ\E)AL W@5e%8Oe2a9@BqA;>k%Xq&ocVJb,+UBig5<$7d6P&[ \-oMN(V$L9-Zh:Ad5:BX,MA;DXKIfk/^N*$=Jk.aH`0@J[!j$2=:"n`MBMQ9i7^=3*,1C>(CCb:d>D$E:<SS_sDR#Li'__=0@P:8Adk!@fp #VCV-.7f-oomcijYrlRXn=GJBJYJ22?V%('PY2M*r-WoYMO.^J"ptAmhE:S*D=H&$2HjHj((N9@m"hI0G3:GK!YP?n:\9@* m4eUI9YWUUKmY9h[40oEmd+dR&RNtFKHdC`-$C\.JpW-F1C3b-XX9DpNSTZ+o(Tli.a<?IaY#)InH4d5%DI8/9V8n^ M7l-YLA+3H?er.9P*MsCAl[>=+H^A<j=\5qh!m+C9fA5A!RV]M49;+EL$d(o9^t;K1,7XUWcF R$<gLg"J`c6k=7tBD>p.th9KA]j*FQ%\FkMeNiq9+?D"mZS<[Qi(O'Ra"22/:)']K/@NJ)pTdka:"<Be8apUmBr70W&R=NbQ'G2+%hsSLV9Wo:WfdWR*APjM0`n-nDAtDpWWgB.e>5kfC$/ljl"[[G6A,o(r_eKjHPWiJt0iJ@3FS!^'rcg2:]^t/(6BJ[trtWG+DP,b6;l?K:[]/RDo?>!a%e'*NOcmqj #^3N#A?N^M49AQ%-cZoMAm)a"F2EM3;Aa`_\:D+(c137HS3F-2T7VYJ)U6'Gf_i-NG89'R'hg+GX`j<r:K$VK6I,SdL/giQc$E\Hf[^C%C <e; Y03*L]L-`q;@s/*797rb)s\0j,#WWr.He<8IT,ES-3-Qnbk>k!7"lZo8@^"*Y[\X\lI(pd>-B[5PP<jN1>FK3rC2Zt\[q->#*e"$f,dN$[k5k&V6:C6KI8fNAD_SIW>@!k*o Bf@&m;H<jhQ+U;+gACds(8qTm2#CQ7J?.CWAVq?7Jce5H@(CQ$IX"7$mATFZC@i>r8C]IjVF_#Zc>q'5P*H6iARNP1B&)$oqWLG#en5kT,em!Q"c1J / hZP _b*6-pp-0CNBP#?^K?\&\a:`T1Y.k:hh:eangGB8K"HY?n 5Hg6^8:oo>=8tKoIPkWsZUg<L5jc/AZ,:A$]K%oM@"MBBY=\P6:;V`!to2CFRDeh6No1/R@n$7rI+2!]F!;VpFaY#)f%#4\<-r6CKbfohI+sMZ Gp/"8(4_WJ>SjN,NIY\nhf\S$rl<#WmAf%j8rFg,K4F3`]8$H=8N';0n+D$oGnVNKU.F-Y7r0Hd*&`K7A7E5X2;OMSf9,LO0Wl]h8U/FW_d ?Upf>?XjPaO.iN9:DQKA<r_2fo'eNeeW12L%-Gl_*$0]20q+;&[391ji h dAXOM7)D)=ZiF7;1+JS>&M>t60_t)/;(,>^LK&eIknR/^DW#U/.m13+4a"V?>#ABV.>*^;#k9&^ZC2.sS<K 'Tc ]()h%]%D_AZP?Jri83@.[C=!VJHM[>o:2aH%=iaA;*TdSZ+?NK:O:LS.[&+_?>`W&7Y**P56Xsd-gE3rO_b=qHI"%^]X76o3 Q )2^(Y^@ZsHYJsq@A]&J4l+E]HO=T7p(`Vs#/bAsTCLE2^mdoZR(,.A8pshE(kWn=EtMh?_h2d/=-bUH^F<'q4.f%H;Ia-BY<A?a<A'[^oD]TUFDen7kF'+AS;\4$@QLbK`!!!Al@I*/B`HrFcS;#s6*-Z98Nm91HVMq.N#Wo)8c+[_gTX3RXlX*?iqqKJ\^r8cX\D>A_q0jfH3i=C+jmYk0+CYEhH&&^<k(kMX?7m2#sF2TAD<`(Q07s7S-_%ijjcKYa.H1fY.IH0[!"%k9N98B3"Vl!UI3OpGA>D+0 (X9_NUfNDd.*PIHHhL;pma#bRED'W#D2f!P1^k9,#<32j+ Yk&UMl,tgAG]Q79kf^s1IpK'1b9?P`:agbT!eLS@+IiIHI6asRAAf,`4WaiXtZ+A<BdQIq/%UH2CCiQN%BaDrAc5pa(OZmb5!fBsO>i8 Rdj/D8UgIo6=g7fc`*YoXU*L[>H*lBtQTA)=Z.OA'f-F8:jTsoDYLr?B<OC0djT0Fq4$qR$rFha3?4HTMIL+0EcXa3iL2;3YWgee]qGV^4J*:h",BA\>]/-ns9,F>^<"F(lH4KmOV8I_M_#ioPU#Wi;;2r*h)a#tr[">j-Abb!>13#]!WK53-A368__:9$hC9h7P?tnB.'O4D*9>7/(nU#\pAGQ9'/ N"H<_f.XbTYln786*;mFsQ.0hP9X'27a8047@Qd%E>a^s>L$:M!Ej07sZ[/IOOAiU,;[9FdG%Xpcnh,\:qc3:WS^JBH[S>AR;bM$OTP)2'QU<hK7J3$Di _mK&H`9M)j>o1.7i5Ucl?C#p6^btCI0) qAl#l&]p(00.8W\at&1CUAa)Dj ^^!IY?d#.K20Q\rAhXnj1b;Bm\")io*SSVTd_P*$+>' jQP*#]re`4@FL)M2!i;HYZ_k pN US1gq*%UBX1fpgiM'+7KGXF4o`-RYY9O.; "g<hBOYXQ#E\lSA4_F4[_)OAkM'i@Y4.?n7\Aa?(&FUtSQWc_JiG-'gn4;g7La5`tHQp0h??<$*mN==;oiD'Td4,^48'iF>>`g,Vg?NZ3<V2J'Hq**>kgA90(#Q1aqkD9.MG&4DFnhr/3Fb:T0`GfgoXL T'S$/X4_8nb1I>SY@9E)6?7M)iS>QfQC*;r&lRCG,Kleps"JCo&T003jGAU.(#"]WnmAG^rHh\h>6qcUC#l<P.ga#j-?+e-S:TPQ(3pWD?[4WRWf:g.SUL2ma`h,LOf!<WMR+'P:n@N2a5,ZoV"nG"dGe`Mq8f#6`9nAkq.`d,;18$@6];R5enP&-GL1HbfT>dB4DHa(T$^$*rO5[hlhLS@q@ZAOlaid]-O['(8o3=.8>?gA>jM=tPW'pX!aX#IgNA<X:QG_,/S` Y0ip/k0g-Y;lc&#RKVJi#Chm%2X.-3qJo5=Zn&GSC<4MEo3<Rq]"Yn4_gl&/\l@b,MsmkcVqN+/JU9XB&ESQmGndB^E'+BX1)LXqIn'KCl)poR0I/?9_)[dML\O&QiNg6OWrZHinWK,-V4R(:e=F&\6 \-E@@&R\?n:;on`&T1$]5@@%kNhEd`@gJ>X,@)]!e;Pk^"\-:mbU*gdLFt-CmZ@3W_567]2V.I3ntMIYBe<MWtZUs&Epl_jaFM"AKZR$ij1n8t8c>n5YbQVaAX9] rc.Q#K&gC`Q%b`NaH1FAIe]A0%qlG3WhTE13oHrOs0(A,[X/q6G8VAT.%gk>+>;;Y#B1,1?s]sWa`'/gmT_+Dd+lVGCLskmrf;T]FXDjit@=b.`mC(LIiY mK&YFUAi$Ka(,,JTH!)9p^-NkGm1HlQG/"%r@@@c)>]7TDL*G$_1l]&=_('hJ2VpX&NE7$(etCjPf"nHDiN/%>KM\@e/;8C#LJHBX,XKl0$tKE4.:KL<BOq4Y4#A?#<dFXjopW_C7sj:bWOT.gr[AO:p1p7UbRZTeBF)p.M-J%WF60^LO5h'K5A?JcNm_Q?'<$)MSC"EcFE6F;"f>;DHF52IVY-aAmsZFX_&7=_Lr;VDip[U<K/_&q' W%O:,nqc6iN:ARs.*c2$[SAi2 E^_#D/8K\=f-&' N"J]GrRQlR!;\3",\plfO>A2D36E[P=^GPJC(:N_[?qZjrI_)ttY9rF(F9 #h"(<@k%A8%"@ktM.$)>cSd.1KlK7WkQZr[TQ]MK+rZ35A5il]IMnqMJb-U92HRGsAXbF_&[hAV4]<G)teYA(g)eIo0cNJ@RR!#KmAG+=5hK#.cS4[Z@MGqnB j*=YBV1?Q."K7fI[_D\]^'rBM0NTDt$2dk!X: E$=1Urh:0?$7a9r;`pnq7)M^i^+a:UMp.A_2:_V2JV)Hag`R=<rr[`/EEk[B@KP>02&;Vr;l=Z(I4cG*0f/91;r/1d*QRY//(WV J_tY,EY+_9eaYE>@tGN=[ ;K0#E3OeCP1UfSMH14#P;(A&JCod>`_qB9H!kDG,\GPVr.>*OS?  Bg>,m@0r f7&G<qRfoS>XIsjJ?]cK2?/^#)snGVDjB*hmgik?/SpPL<]$*,HkGbmPJa7Z,H<;l_"-//L$Df25%(g +G`X>HiIa<rqa `R$$\ADIUrCd'K>m< [A%dkdB1856D3P#dGQg1?_a[Q8bnRAmskmAkH=p;?WMKgsGB9HB"YDEZN/=Eb[]C&!+Vp@^lGRH1p$G_FG;O:AA*hGoe=4>6:C)ABX5!;/o2M+X? 1t&>8^FmUO\s.UmMO(>a@mR08HJA4)@dEP2mn`/'&+]k!e8L2Q32*'r,Ad;D?ACnc&*o9p@rEV^D7JG$SZLS1i2q51:sgrDtWXI?4Km1c,NHe&P2rUlhea.f"*o+ksBL<_F\pf+sD`n8](PWH$h/G4df`THCo7-6,&4d,C";%*UFQoWOMWrG#T_a+[dQH&[1,\#!Freo'D1">W)d[=bh6YD/@YURLi]GDU0EX1f!Nj(f'^Kea5K1+UO#f1"O!q,hA`]ior/]BZ(iQd#H_2jj.*kcAtq[Bk@hhCpB.Hb+Ud%@A]NBY,^Uh4^m)?2ORP,C$q#pNBkU6NBB#_YV"_,GeZU-'VSU.RRPn5r3'rm3^mXr*&%$"diWq&[RM$G7(+PjT/plUcS\Q*UA-YWn\4;e),MoMYMXV3Q/r$MoHnhrnpqn/)#InrT8:G\JRA>GRfk@t(FTpr!OcjJ<W6GH6DV\Q@M-3ikN51o?RWO'I)$'Kk3A72P.-iZEJsUW3`S=YYth)=,LLDMiWK!EO4R4kT-&*=^AA#ZPi-74k2H=Bo13;m2.%AGP*cH3?9n=2m-"9D$`f5%>_=K8(,`_Fo<gQL%>U[-A<4@Ip3c'M36V+2EmLU/2sb?Ad9];d>t&_NEGhdbs_<#['6:N;tnY%Uk#-8;t;VmFEms(!&07?`?2"0VR"7Xg%/?A;k>A\,(1,Aj,srR9)%qJd<l,g3s<f.K05L`\<$A]4AHnZNJ<\OM.m[LJRU+);H]_']QV(i$oTOfHDaj<BkZH@mGif$*e@knQlPnq%dhS\S!iLoe$&'_(@lK1gR@C<Qjq8>ji<+M*5M+pU9H"eW?3jrE`apa!;qV0UKIT6R?\TY,a3oWBl9k<pXr;.*r&[MmmQAA%$oLI` GEkfsTPN-%5r,"]B=Y[fd39P`"HnPA7lAGsHW@NP&oN!>34;P49"mtO/RK EP6mMmi9HYi%TG$AslA@=M]cN8A'M>#=-[bGdLh9cOXh1.N)?H_kHo4nH\6II>Lq5'VWI&56#\'%qn,L[EGALMb<q#4nB+Nra<c7]O;((3`G=PrQ*=T>lWhAE\]fTQpVrbO'((nJG.^]=bS]'A3_YL^(HM%V-GZS@"B[UtH1\%)-eN9=<NT=e"V$[N-JMAW4*AfN=N&Tjr#5U6;AE0lAA Y:/hmF"&1\/GoZOC@7T'NWX]r_47d6\g_kjXgt#E)E69NBN9%(5X;7n!L*H:.Fc<lU5#,H,gglb>R:Bn6S+se&9M9:gP81lj*h(8RWj`E\Lq"L2$W/rUCCI:Ylb'2XWA?c&=C8_5/P86_fhg05B<=NLpDcR ;rg' SE8'L%mUI-9Xa**8@6'WJ,TTYjO66V`8A#olMgs$2_b".Q23Ai"nNI"4ECibgbEnr$8OD 4]3b=#;A@G-.VYKM"PKmq0P7,-0eSZgl>=Op60pU6=;A%U'LW4 MI;KR#qa;"ILAqjM000Gkq9KkH+;(:*.!c8<1tjH$A=c@Y./ikk)r;ZV*fJ]<(JA$teH/<J04O=0VcRUXfY&Zed]*E(B?4G_2PA9cAUn%U$\j^AJYc1,UA!SkheN.Ve>'Eg"Pfo"+8<H=Fq)Hijb,J@;E\KKOI>`/TB-r(% l2K'E:_Wf;5t!rcUpA%Fr3#5(\+PV0Jl;;Z'+D''@FS%Sr^Pi'=sGE'&;ATs`;GiaSBTjPkdiEce?k/a6+16dKP.?n5h3SX<hbR+Ms>Oa,c@.48=gqN/!sRpJ5G$)J2Y#.8no8d^:fVo\Q30HaWP1+l/]"K.oG;H_4AE,rd]L'G5(:CgAqFsoC:2DtH94<,D\=!CiYV8d0(j9rt-CaR*$#'pL_kZm????VMfoN?tIlB=cJ>HOVH:$]P-1mHoXXZ"I00Wdq5j]E!)&#S9n=%VV67\@B*9?CjlV>AD:J8/o%PG9[lBV'3)!"]%Z-p, -B#[a9MkZNTQ(V>Oh1+L!q6?]jc()`?20W"6I8HA\%4'q9J1S]rAb`Pas.Ts%7lWog6XQ\ *S6dMc,-Rd^C?\@bIFq` 3jO+o,j-29Wp!mN%e3P8_La[A!*UbM+mhJri`a!$#8=\,J.(->;/%$%L<^MRThi"s%oPQ,=?'4\1;SF3b@/$HeC]P&,(^;Sg0V6ZJ<NGL*Q1g/K$?F FF6R0Q1^e]nX3(g08HgECp[HHH*eG;+K>/O%k_qF:H+!q<)b(]3>^VC(@e,FT1l6!j=Q\"rVSSZjR9N]_<\s*@15N#06gt:J%8%4EFbk<e;HkN(H7g7<G?L%R-1Sek()B\\%#E=E>tD1BZWA`RK/l@K43K#1.W:;jQE)cN1Cp@A?@RM;<lHd)q!oq9[W O5UKpC`#88Aja0i.fn">`%>+]5[oDL;N(+Bitm"Vk^6VJB-[rJ#6#GMH*je^)pM).U9lZGQXE?h?jkXoZ .G:T'E<\3#0apXS(#()fj@^0A8l3S"e?r3E/A2]hbSU\Y%JY$<&Zd)"cHs`jNf_8)*K75EGXaG02T4GY42/?X>#HNEHP?]ntgZ'l=I2CTa"TJ#fELgaMTZ@X/0%?s3%c&#Xd"$Zgo[oG?)?TBSoC9^%"\5)4Ccs$l"k(skSq`+C;D9pCgi$PkmfV,sBPInTf[s) #"q=KbP\lE$Et\pfaepfX@<=qHrj1) E!A2W:oFRZUed;2ZF4V9NqmU$>/e$2h]rHJ2bl.1H61)5bZ@H4I/e?T.3cN=YA3<fpigZ"fJ$$!$n&tQ2N:fO'Gi(CHMe0L2H(Q8M"7Q\<#n?gHFi)# Vk+^pp:rfc`cA<l\T_fUFT<P/5+<LMHET\=@SJqE=R@DMj\gjZ51b^=(mNa .:r)YlhTI-/4nnZ^tJ@=LH@SOOAS4.Hq.2 QseF]ZX?R QdN]`TRjeb5p!IUjr(nte;KaZ8Hh=]>qarbFsQY+;Ms_0/m&d$l-.+SaG#GPR0\K/;H/E9S-9llAZ0Ge&3-[X>B3m[^;$r\NlKb=ZgkVl0P?OrNR(F^^NDQgV0\N_K$8h&.1?QAE/ada%f\"NL&VYpfk_Ah%k.g$VrU%15WYcA"bdAKY<KP:fs9a6d<j\XaGI4i,Ui^e,,si>b@*h/<&O5t` 2dUJD@Ai. [nKs:3.U9iKp4ANWJE<Xft@nm/K5opd>MZN8n?CrqG_Cr/q+h#3L%\)HkT6)OP4o([CsG9@L;-0#f8JNGYFc %o]n@IjLJCg>af8B89D0`mmRsTD6QPP'2EUOdV02/23/07NX]dBAC^CHln(7b&DGV4GdSVE>5MT@:g'<(I%E@Eoih:L"D@)2[rg)3@Ctrb'2()Oe1/7MpO"2A!57c_[-A;*]<ab6$hH_FoFW.%r;S>N_"2&;A/k9=!Ha7BYAq+'1(N;t_DA32ml09.J4RXaI4#NK'=8>H2P8g]9g;_#E'H\7R?1'%l3RUl;WT[i>.YkaKU#1IH4?YI,,CLSHVBVr=S@Xk4TA?%K`q#\YjT$Bq:Sb#U;R;%WZANs+Wf/eWHj*.,ZRi>mh7j$[Sn7m8H_&gH+-!e(Z7TLDOqI;pbJYA,aF<Its&KI5Q?;_E@hONF:Pq(rr`smD9UoHEaqdoj7 qm3G(c+P7Qcm[o&:+LC7]p/GXXH80F33??MYp l_8q5s,)VkZeJ?#s)cq(/fAh"g\n`j$jm;afp.&SqD$&]X,EAK^8D[Ag>MX#t*/ASaW#+)o9gr:/]9>XE_es6dO3RUPQC>]HS%)#b_%[Z^g0rm^q5W>[Y424TcF,mi0<'JU3o_eGcqKE%)Vj8+1MM7HFt5.Z2YcZ<f\ieZ*tWeh5POX]M69eib0s`T`VN-g-)Ai3ac8F%qN(+o Mt0:fTXRJXA'X,45k',JrAi_\RB-mVAS 4/a7A'm/ A./Q$bc/0JQIbsR"9&MEdBsH4IopG:mWt!N`-8kbFXdMNB(6?!^ag!hF"&,*oe@?9ttjm9i&DI2a#()7K>?WW4W*m$U@(O1-"imf_%1kgAVHRJ(:GptA!1id\<;'3mV][Q,bqEk%8 L/[KbsDk\h`pirL5\pp/?to+NK=Q= .s[OHR. 3>*\Yt4=6G5&2U1Oqq+bm8dZEH.Qd_Gc)(Ze;&Zn?<R^f<=.mf-Db]q,dKNX;2F5/dde2"'/QQFLe+qDI`#kP;KiWnG !J:r^IAU/Pcr3aPf:0Zr$Gl']d2&VGS;W1&4-!PaKF]B&RZ#c8tQ>:jC(3^2-W6*m*5:GrPS(JE&#MDIL(Td&3nrl-ge87?mtq )"(3$r_JCWcj'VRmd-24+.j3I4&X5fMb[sntUDWci$*K 3U:[]/YZLn08 %hb6GRFRW2U(p56 /Nq-Z]3r81kDG#p+E'T-Hhq$"5G"e)irQd0J9"&QB`ZffD&5!e]$];IfWsQU?gLS+9U08.4XroA+;s?0-k2d2R8`.m/UlS])l7$J)j`1:I-tffj$DSX)t#U;KkO/P'0^o@Sj+MO^lF!tAs<D\^<;A6`-An;39rpZW#02dl`9^4A^s5A3X(UFH@[Bs1D+V[bg2VIfWcb^@Ltj#OP MW[7DmH41Z$0CIpW%j4eU0A3PgqetLjC,=sD)sYWS#Qg&Hgd4j$oG>>m&%XS'RYdC4Z<1_FY'[H".-;[&NP^ ]2nHOm!^RO:V9GEm'8si<nHJf(X$e8+JhD8+U/"^,CsYRf(!P'ZA$mgPZ:#dg=+gB&<mS>fqpcZ>l6Z1OiJkCGse2B!IL7\YP'cJ_6!CEg.J)fCi <5.UfrRlDY'&""3e`O"?sD7e:YrWai>;a_Bn#fZF)#8h_G5$Bisde?Jomn^@o'1>5LO`NbpW6?NJ!S5'iVQqi1862S_)o7><'O+ p4$/d!dZR(.&iplrrV7Kr@Vi ^G8?P8sn)XZ4<T^qU .j6tQ@a'n(%*?Grc[>)1L`^F/K1Q?`'8lA;DLDDmp5VMbpi+7GOd2$:pD<6%AM(Mh0kg?jD?NBSFW,6L&[PXNo$YgY//Ac[2+A7X7R7ZP#1')sAEN]_A2[K:M9h9lVE#\=;+Do&cnCp?3"'S$0YsF!7Dt><V:!X%lT?orUNR)A4#N:Wr'FMKc7_fD(e1g_hkV^'-<cX'9P=H+a'CV=p/?KR]ADqm->Sa_MIp4BAFOHZBni2f$(1jQ1@C#no]N#j)LV*p6MT_)Ze9rF9ql89QBsGj2>3%2<_@#.W(\G+mcm'+[q'*Oc4a%E/A]MSncGaf;B(',QCGP2eL@%7D+g0%!FSLl]]L*.F;o)qZ@63<&F\).cDE<&2e -(5O<;2G8X5e[j:U]G-5U.WM)5#40mQAUSr)E":a*l7I&W[@*ZlT1ES<N^/Es:#1K"&\+SA@Z=nK.1"Gij5<9$]Kfdf0UHC-!k*_Z;Gjg=V>J3OQZ1@1cL*Ac<]MJd<hGM;pl6A]T\\bX7( Lj',)2ttD'qk!Pk9D:i^GOp`)eUE.KKsD)H]cBi5YJh<itnm&TS2d(/jQLQ+d*DRNs$!LanT  P"$'A R]pOo-3I/#?CC4GPR5GJsO0ijDn8g97>+%.USp+(=CAcI)_hnADV^s-GW6Fm+r,?$S28i^PJ'GsY<>)7<+b$PWq c'jtT#nr#AXVBFX,pcM`%OeGKWT7/!SqaqH9@X57F#JI*FKA_/1:*s&H#XO;-sOOS&G0i`]P"^1jo5W6>$%Bs:HgZ.9,WK3DcQ`W,aP+4:s5AWjM35_1)dks,7`f-VJOsE;D:c)H=7FZ/VC,t'csDfF%/Fp*T<ZFj?a(oN^hn:]s)#:OGSs*$2S$;,>?@ie*VKUWkGTsa<9Ud,l;kR>/7jjs-eH4^j=VF.l@Tl7a,ApLb<HTN>j,?PmL*t37#R)TVNE>9'LjZl^+@ha;WR'X9FjOU*Ot?k+#YE:7G>nW+<AT'8p!TUpZ,+]V>rDPR(L9MJY>ap?'1 A\EZK$bliYn&5&oT<Yl>P!D!K%BS[U!j;b0pY2 L*gBC<m%C\(L=IkV756`'1SsB(H!-k3 *5Cp_??X"'pC+0rtdLQ*BSAV@Bt[tcP?DWT5b9M9X&04:dj]&+9"Z*Y](68fF-,%BL5#V6tDV%:U!+r#q<#KG?*j,nJD\i[d/hM)>lCjlt*&<1Ko`FXB\:*ZbD]9K#`-YKZ&+g5h)F/^=97iE!ApL^rdR?1".l(e)t!h<0lg^;6!4@#1jn\Q<^$LBt\;  8`9V<`g4LC(so`<% sAY*a.P'Y=M>q-C?;k!?knDk!pZ%%$5K`XW,b8H1k9,)sEbWjs4*AC;!&H6fafG:Al,0c,eWQ4>,lDnFSf.DK;*`F7`b$WmhO_ZdOa01Uo#A?,RVD=,@H-%;/\CBD/-Jb")HH!(0XgSnIhK[%b5-/h^?Wq0Q'n!d.NHig]\K`5c"X^b"h&t,Pg- W"[X(gqPQF4W/$GtB;%AJ6[#VaHTgV8HNNV2^rKR%R_"MU:Y+-Ms4nB,1#ArtADMSY=\dYXe<h>Q])g\M!2cJg#SPCHqh711ObJk&HV"qQ^od<LfK@:FV'm;$t^k:qE>*Jh2f/+m9;\Q"@IG$0JE/Sis9XS_2T!;K [nL+VWJG!s0&:@klHsX@(f*4R/`sPYR'>8og.[LK-Bb cq+Zt6JFbdaM\n;o,ohqe<mOA$3@5dfO-)pI,e#[QOo.k"Wl2h[Q'jk0[:4p!LVWA.+l\,1cRTL.oogstQ#6:.1=.4)9q92c1]LcaJ-K'n=W!^^Mpg`5/<(6>1r 2p&'i)&bEGE.ftQfZIsRh\C4H=>3M]d5@c+3?F`]MNZeKh:/[(JWbXNa]q`?F4jl8OJEQFI\>#B-t1r?1m_[I= 5:BHcP@3$d+aG"8;Mg#TL4.lT2A"pmGo@a"&nbID9)DCW_SVJeZBCClsPG/03gddPG7D@!A\Y&j5s93d:6kT'LX$Yt7gEP_L?(p.#r=*b-'sc@SE6F[(>4nn(ZoC<8AJ*k@(Ua(mCNt,N@b>qm,o^LQ9W&V^9A5I%Qh;RJ\E+\BQ%IoG(!3GO>l>CAi(a%mmB*\4V9(lAI2J%?7dS^3/b0--0g25foi="!]`r3B`ist5eWDsqF'GNI9q%#TmbQf.L#ReE<pcfAT,ODsQ[38^4 dQC[NUX3P9ZeL!J]asH>ont*o+oebK/OH=B+;*tiAsbQsnUFeLIQ?j]kr1rjM2TWiEbkmP1]eKPmR9/A]t!Te=W<JgQ4Q0/b`'Z2dTo?)_"hmsS0EXLo; Y98sYA;nh[NAKRd;0gbtB/A43^d6"IoRjt;5&j>>9A57.dQP^mn2Vob'5jY,5orT*p5*`'@'^GEG[C`A-saa<Y)pjZ"O++=,Y?BH_sB-[>a#cQUo^#>i+4H6<B!1QeG]PBn;8jSNcNlROM#Q2VJGS)E\":::,=0,SBCbO6QMNB.6FlAD"Bc!&H]M=f/>tEkHi4@6(]#W.HQT0FQ0IL%=-(!r9^!k2MWXTN-dt^BU/'"0f4tZ>gQ^4/6>3:kb!8h <NN2@l!ke8s,L*i$bemn\bX?h7&Hl(1ZC>gZ#`[kD7QBPK8AH9/loBF`d+&(.72#=JC!egf 95%>9#IF]0.T-&Y%IUD+tLR1:C\&R!rZ9Uf2>LjOMn%Xn; YMQ5C[f(UhZ3nAb,CO7LW7$^!o,bB5VRhSt"i4i::S=7J5X[ .Rp!-E5#FQN;+qI]7,R(:SX1%qCWK,m\9="cesMOMHp$pS1T0 \C^,?Jt;_Mm4]=i1X<C/\!][_>CD!spSN?1KInk`qiFiWF.]NS(HN]_bh:VgO7'\etNMBrm,/4>&o`W+tf4 -FUmm5\r3[ALm9[dUJ').^8);Y^`3P'A^iVS<t ^r_.4hA5Gb3L"oK2-X0CK?l0&@(O\_RZ+@__a_MCgFHIh>jaXGN/sQhOITrQaU"p&6?$4!q6CE)>Glm2pGe-)AX@4V,XDT $`)7npm8=e%*!>2FF^aXQYV_[2d5C7I_-[j]DE^\J#Q&AMW!$W]G3+N,.\?h>%o0s0o\gqVHL:%N]iL=]9,j(m/Ap5moYVK^T"Sc(\^qk1pe33N=`j(<*V:b,(#h;6rS8iq1A)RBW@!G7O&V]l9?B;Mm+8<-fWe]Zo5d%VXW\h9a4%4o`NKq0B/n<Qqg>]i1@%9GQ^2^Q5k*.$=LJQ8kXREg(8RK8c#.^FYVT@_$.N,j'sOiLfPX4ePXH;)c3jd-[9Te2f;dqhqs=S1Xcl&KmS%I(;Nrp,*7Z58NA/4OXlQ?[%3.2co(`#KCT;3SJejOR')!?]^^1^-UYY/.8 823gU]>h=#BjfAn=*&mDcSKpPsL(G4KgA.5%@acdimWp?ef:eiQ*@X)Z)MZ-pe72V)P]e l-A!=/Z<%80KA5*$0F@:Tt%qDNs4^e.Z]CFA^S"JhaB7r?A-n=otK*Vi#)<58lo/R4l).aDAeLSFsno`1Z#P3t2GC3FAal78/hoK,>'/'Z>h`:8[-`^7G-#Q7d.Vp.O^b-\#E:q86[UP@32gn-R4$-dN'48YiPh=Wj/H.K[^>0e],)7j6tnNq=G9(lHZd=*24"@WP!\.rC_R3V>W f0CF;SKZTE1ZgZc?$p&`.eE]:5^?<`]T")RtQJiXFI%U$Y]+cc[ 33SM^_RGC<;&B^XnoL>"4g)6RaHjX:)!P%EA_91FCViV<?f`Mp+$9Q'@=01Ct*#SLa.Nm3aJ#E/iHq1+[%F0!VN91T[02@_*^D^ng:#qUmANIgE7S)_,@0RGs^n$asRjL"/[_dQ;WB(D@i]m0lDbUF4HEd4pkdbEO-I@W&S0#J-G;R%`S-!BSR3'MP*H(Y]#kOg_4<>7)"lR3HYXWpet\#r>+f`X&g[tAHI9iZ+RB*!4/jP:Wn?`*A5Y$b!eWe_[Z$M\<`@OQm4&(RWRNg4<Q-K5Xk67/??eG+CsL^`(#GWOqedc:](f HK9J\R>@k^D(KhZ.*?K#=On8L5sGd?::5C67$Aa[.t)9S\1"(id(R)-O5 GIcCO;05;l4;MQ4)K^-i;UHS ^Y2]!ac8r=K9#i0(YVENL_>WO`dk'?[m0AQOSqX_UDGWBkhS,.@W)J6s0aAdj3Tk>I' $ghFc!V[+,SS!:sAIg*lao;?1Ule(YLR*M5hgS0sRY-ULD%8"6"Y*CFA(V6hW%KE\=V2D%:,63r^g08WZV:OD'?-pdNq7Xs i$aSa^,'saNZ.?M+g!YO(Qs]>N?IUY?TSA)=5QmS!@%U6W!MQ#Q3rS[tnb._ab&BM,OnhAE$QlJXT*H3MH$jKa.1sV+aEY5p:[5LgFE[+n01)l/B6iA'4kB6NV!#.,^LAK]r9Yi?mG?VoM9RkW6j96cnWCLG`4EGS+b)'_!4tAfYJN)H,'[:^'7G02\eEZVFkL^b1C5V<N/QILA0JP4N5e7[lRZ!jLY4#!>W5%-HC5 Rb8"E%5!fJ#@l51_4a+j>&\36@h;AW;GpNcg)QVBS:SJn.CE*(5p'FqT_fe$8=ILSaA]KqU-'S-51i*AQU5d\m<5'VZt_nJFYYPa$h1N<aOY7$A=DAQ`pQ>WY^[2Pn8rm[^A$K5!86p8g@_m@i6oAIE4ScABg2^@1#5c&V$G%b6qXMEWFP=hZ1I4@2,Z9OE6AjkPDrgAWXS!Qk]M<*%H0ck/5Q\[B/%)R`\]%?/8K-\VM3NF$W1s@Dp=6+bk#H2KV`b989I@RUiQ2[\5LJkcA#MD/ah$-g4GFC2&/>F][OmO0nT'ATVfl+JtK?5OeOlmXOsmW_]2:a-*#!EDefH(RA&d3hBVH51b`JNNcZjFmZW8LhhCfRdsX_;[LPk0^Amr'Y]MaFM>&"Ah@5oag&U>0sgOh4mqCk96t-5CDAAIrtBjMt6!'K(j/!Y (h/'9m3N8:?B".D<&37kX3Vd?kdMId!r2N VO :#/M9pebF+)s8_`k-jZ KhD<2Qi; ]"&.X8Yh=`_iN84L^>.,okJOs#e\:V9)_As;W7&fsW\9M9A?bpeq4[BAJj)^GanF;dRBATt!MoskAbDbjmkS7)(,J#<3n-$hfAM lP\F0Go-'khS`KU^>%d>-ROR%t?Jst90nsR3`9OO+mE6X\japPR"54,(bhMjc$";$h-e_H5=tp,[YicH^1Y`<AXO_"0M`/Mda?f4A2.oYt0CKf]+2D$h@C<>#K5%o%)D>QD:  scf`r2dgX">cHlTH:>O@ZHq=r1MS^$gGN'Q'_MHD5n%7m9At6WGIAXS'%V*C%I(Hc@=aKUe]sWo LZG9-<nfnSKC.$E-4H RAi9N)C]jMJ]]n713<10-g^4@GNOiKK'M;3dM%Zgns9dALe!S_;b-N7\_V6-b ]Z:=+idPs8X.[G/6NRd/i$760^(&)m8U:sq/4TX#[Xf(<Oc[[%aip8`-\7$[o[(]V]AKF[4"T*h#4KapX^t(X(<?A./%YC)@F66Q&R<U7kl"G;"OCU:G;5bYh(Y31:N=F\]eaJBW0&'U3t3N+=b$$4Q*i`%Q?GA6Q qf0#0,: blqbON(T+J0$D<aD?;-%#`'Qc+bh.7ppWMO@a#^$l^+#Jq[B7"kYcrpXURd#0tV!KA^@bn@'!nEW=i&o .-Hm[.B:Y&q:dT+Jd)4!/:Hqa1R;P"q- s/a8#:BWc$^ VO2_\aXPY/p[<@oIPZ.m_&A+>?USAg,kG:bZNZ\<GShNa<t)&ROnCA1S )RZ4@VQ<`6'(RA>Q2Z@-aM^l5CFCQKa%(M=APehR>Q;-8-0P/!-'q 3#apC":a*D'E*a9[*!Q^"l-Bf=@@Llb6AtdX@D]E)T@rUe^+CUqm:o'']Tc>hSVnI0*mTmJ@r5`k9@Fk`R)2 ?`!FIV[Km(<W:a`+GdRnS^/q]o<>Ps)aAdN?*,Qk!,[^72@"0Fc!?'pr2jVr;W,Sc6>C*Ttp33,+@[p,/0^N]>b")p*3^c:p1UULHW'`Be"Q]%:>>!lJb:/f`j-Gisba?UA#G)FA^tE[=KQFMt-s-NVI\03s>h;`@E-D6t_6L @ Hq(Yf[.O(@;"<em,i[#LGKDo>R2i)7l/>4_`_NaT19i26)Jr_+d_$s X:\&;O%@[( :%Z-,$!9Ee@r5MHL6G8&?^!Adb]e@oD+9ghjPrk8-A&1KfVNA+1Yf1;04dqhb-<>5[#LJU#;t1K/!e;]$c_eMG0s+F%Y'6$A/5GJ;U])jA/JK4Si03G$`^7<RL&jVLMFT<-ZXTDbDX3ld1)J1Cbhh^/B\_ErP#'X)h#l2f4M6tND7o2H I1,[N6(Tp3Z=eZOL(CjFp$:kqAnLJ9,LGG>A0J@g10a;Z*B3IjG4@@R$G&oYI0W=!m6CaZ96WZSC7"=QM=FKpoGA)m`Md7:.amAMa5BToXgk@PAYXElF[]A@U\>AAU]t>MALHRkqRZ<(*o8coNQks[i(rlXl1>/#Nn2`GSaAE=ab>6Rt_` +=p'e9f#9QVU[#UgLV7IM*&6lRf8(.'-DNK>ZTA;/hkV`1&k+A8n9!6JO(3fb_;O3.[ QX4+o^09RMK0-'bi']\J\g+#04UmYei)g]%=#-ZG&PYQbY34(8D$6Q!PKT$+U2CrpR"[K6,\XAL'El-h&TJ%VJ'-qsL=qVdGNJo`V0bn[)oeX7S"qqLl50T=h*(d]Y<Y8VSSdiF5RH('QbC$Bf=O"D67NT7305XY\ h:D3X,]a0/V\MCg7T)g1dsbWM0GtOtk,;$3+aorA_K?1fY$qajObBWn#$1s?ht@SKDj"mt5niIY 3Y-o/CU)9sWM]_G.8pk?P"3S:B<@$PdEFpqD;#,+:T[K7"'ABO%bFMoe)8H!AK]$$)ljk)'pMCI=)J'mo!5>o@@C)+)(6QDJ_[O&I=[:(O6ABIPAg"jFg+gm0=kl,GMtT<#L@<Q]7Dr\'SEZo> !sjU%S85O.iG`1SptR!Bks[AQ':h,\FM_#p69ZCI:VR6M1M/?ASYkm \ng;kEZ"<+31"U@(`*ar^?jd&M5Aie`T.RNs2$H;0BZqep.33K $CsM-4)9Af16*)TE>rZ+5b0;-"' &edIKN(`N7A8)8qsrW>)_s%d4f3o)lsG9jMBG ;1nS^#QE#YkA?,R6R>JfK=%&j]0*(&6p3icNN$h.:P1_t=!00#0l!SXlAPP?>03)\99)GUBkPlAWf`6&?@!l.BZqq8D n6sCeXg%M:EK2`%m1C$_kF+PW%IS@.%9s/CF(Og_:hT5 MJR6W<-:S99' d!:PgHA=.RG6-bUAcd1.5eY7&g]Ca1,;U?XLD]J)\l\rkG=Q4ML#9;HD$> i:;On'i:k4G:%F_6i[FG'2V<>k?^b6.lF;leO!G<Z-8O#6C._b409et0Kj5+R'>N>`T]$\mH.J9*mdF^0kNC:24 !5(S<Yp-EAT\_FUF(H n0ZD*M#Z' /.kCt)0V7Z/c]O3Uc&s:3r9hrb;Z,1@i]1SXUBH31IG0TC*=j!LiqoAPG;seVIL,qk`!TUl6f`n=R]YGQA>@X[AJ7 Q2h[K:1^Ab*J"56tm<F/d)&@'B/5l_TWcaVrsH@:fBV ?@,k*A[A$;=.%cI/LjP`%q2ERL,Y&"MX&tP"PP]H7M]Sq92W1r4A>B%7$Rln"q&[h&=,BYh_At:?asAr#-fM)n]lK@%lA)h=%.%-X+LM8b=K9`6&<oH-4n=2MKM.GK,2-<i:#U3cl$9`$j?go'q<H1PirCsT]NA"&O!@./N\S71$T?<Gg@Z[pLsh6fn/46s?PZGT&  sVC/ln3O'Y@ Cq3jnT,3RP^+UQVLUWcL,mQhb2CMk?X3dHB$W4$0:,e89_Ith/_BH!!e_+BZVLE_CaN(%+#)2TTG'XgiVDP78AX*qS]'XFs"_Cs.lJp%J.7)dI?MIQHhBI#!]`cW-*bXoR[Z%d^/;3p! Rkhk:h70^!LF>;$0<iZm8b@KX)5^%hN2fC6'"Hs+e2ij=`;RHdXch*aMf*;;X-Fs$_)C$+*Gbb5rYOtpcOX0("e=j[O$D4P[Z=) q?4;)&l]I; B,=gj=/DlS(7tBs(a\dlM6E=[" A&/G^`")L*M^Gt=m"/CSJkht5$eY4I/(Ar+-gAqSD9Er<o8r;hYj#@rA:H*W@SAi-ApE-;K.V&Sc;LC?1Tq[0%@Aagb11@</ lQ0_2aaXcQf?0aT,;Y$iqdWe`>D,5X$QHS`hNP3m9tZN=s#:5kd6!Tc=&LW7br/$?6YN@L0E4h/Y&:DeAB64,D!osg%\Ij0A W(0A:QVGh*ne^n$m%K0tPW969Gqf85jH[*=2;8V%gpHV3KH'bqZj#i]QImc!'!rKVP5AP6l1K9^T:&DmQla*='?X1SgmA>;@'>K!n7mL%]]L+L_)NE*c36S6pRk.&P,#AFhISXq1d:(E@)ltEIq2Ik&KN[.<r%g]Q\-FiNh/1'$/EfYT1P5n=#9[AEJZK;pMZ$D<gj;F[!q^MOT\MIjM9JWkR8Qt0(4flaaE.t\Or^!pR*hS?AP(IG-H--$XOm?TE<H7V_UWJA@aEX`I3'H)@b!#obCq`4b!8_XIMlshUMAW*R'+,M9mfI)jF[1H"dA^AJM]#fXN$Af3F6"a9]`.!FW8h<gk;nliho6mfgYmBs`(r=@9Bl%&/STZhMnNkqA4jX=LjB5aN;a:(pU[@e>Ln(AH\qqX/[87\(P]rM3Q[F 8hE:![%M/*2V3U.Ncn$8eT20-@NA*RNt%p_-"W]/fsC(Nop\Am"f.VW[0,jQfLCPm#XBBE2U^sV]<H9&NTO0^gG8 M$'Lb2XLO,+Lc7+pgAVV\NO/=@:$5ACqg3$_krG^q:(KJ;bRD-[`/`$%P,ipR*5Ns+f@SdO?o41O6gPbKd33[NQH%;0S;d(-R@ P<_;.> GasoT^9Q (HDl.MMKbU,fNR>.[N28U;d>Q<NcS*c!1Aka&Y@rX0abd\tHKDEVgKo5dBfS#qgsSll_;)EFE.c(/0s+?<0,m^76Keqie5]oH(KXX6NsbAlBUleIO?J6?a,$:j$!j6"HNP&$K\o\AfDK1\F@Ie,"AdK7=Jg16bo*#^KIm$`A],19K@*J3_b.j:Db 1 QAn<Lg-ADSI12S;,7F,EX#/b/D(',e8=sCVAP)nVQX2(Z2o5K<g"Kj1]I4A6[d7M+!*_gP@gog$X7e*3:2h'gMc3K;0>Heeg?RrMJ5diRlXW4OdOO'Y<sO33AnBs2ldD1]`67W _`^/#+5(aC4YCA@lh?& ^``Ab<kk=apN&1l!:1YgajhalDN)Ek>SL[Tj0KE2k1A;g,+3da@N>X&iR*DVB$hgOrB.0q%iA[/LU!#f-s.1gh/nd,8cK<B0p-.p')jE[X`VR6-2V9*0":](e<g6fHl76l[9+TFDN5P=t;Qk?(tl^XccUe)QT'4^51$*NRh#iW@OC>*6!p7sFhgmi0a*q-g(t]^eOQCrO"-[SH0#0o0Z^pJZXOO`Z9EaV`C?^m#Iog#sYVgm-hfNIBGUR3tebZtKE'aN#Mr<QcE@'<M_<Q/Lr"oCL&>Qo6<1k,s(8#k-p4spe`o#\eUG?<n0!i@$F]M#.N.AVCZ.],UR--X-C`,@C"PUjhK(Q0N[T3k]79*lSX;DFl >- .;tNl>H9tlP)mr3Z$!'o+jX95fDM[t2"1G?ADrG9j7EM0<l/R1G]jl!>,;WB-FpEm$sE[&"::Pnqq3/@H(,bW,f/KJZimq<PPgt_AK\bmbD&DVao2:fV$Bdk3t.K5N\&h:?=sh33e\R2b=9lFS.P10#K.k(VeKncUo%/:m[L3f+)&8,fcf_k<9R[*K=[Q<nX,^UYSeUOG1dTB2,)-ne.LXMrB9#N<smqQ),mFIpR`gC6ct73F)hpY8N.bhVGhfXb&DJR9b-[" \sg`Dqf4a`mH7c1em3m<1Pl4KX9_`cg)b8jcVAXDIQ]dtH<`3^n\?M?,e)]P+RV4`A*CAN*tdEE2^ffnrZgAKXb"'@K'J dX?)Ka 2.>(WYlJ"eRMO`TXOpSYM6-Ob&d6S+Sf&+!Yg]4+A=qH5S)3d7*\mdiP?Amt?[ANU>OW#L8teRfSZ[^67<[f: _tX'AEHnAE[W.oCg8a$Pt_g`'hUe9L]R)93.*,M<X0R&t@#q\qkOhcn23?on@ZHTU-;\qS@%<;P:?h>W!-2]Z`.hh(;BT)2V/2m(LY&)<Kr;3*d5[DL&?fV[n-OCocEE;@Gs'd_.%,sI__2VpRl*CpYCnVl0l7O4V["'L><[1I">#]<<LW]%L?,[pOC<!` JKt*S65UOW;AVD#.KbR[<q!D&>[nSVMi+"9Nf1>_(KKoG<m^A[ATiW!kZ)F+$1Hoj`EBRBOaE;T>9mT&s&_k\g7%o,qZJDOtRAl[#@\AI&^*<VAE49^JjXON0(7pqP%`,!Pbo>fm!No$e7*4r+i^E^T<k>s/=osO'Q.<t')"5*1/D3Ng+c!^PeoFI?PIX'k1!?]NeMC#AGT"GqEZBf'HB2U)?#j<$%WZcl389349(Rin)]>`OSr_Y,L0TdQO!Gt#A)+2t^X?Li6\p+PB-4A(eI4$G<G2KGQCFMGB`8ae;T.@a?S>BrC47;&FdG2AB.#Mf-_fP#W@ro;\jcEr0/ct12[+N%<TWbK ,n &m!ZBKtjXU]f?C7\lVc[Q/PRQD#jDUU6<\@9Do%9S'n1cC3E#<*&^lW:VMc7%mA>="D"UF\qhD3nJCm ptMaZ!-bS2:;0P>&[T]k]a$b-3XT\-'P=KL]A%Xh70nX:Uaff`i#Pgf,edW'_GKg<gcCaiTOTpt/Te5T81ALM\++"$7jOIBZ@GZ@J1@d_UKg0o?[&'U:Y@4D")CUMik)6'Ob="2E@5\8mOs;$4SB/49L+hD)J;m_dSZl0.JB`=tM^bg4m?VN.n5o&bh@hR1&.2LP$Lb?gRk "c?"[gQ/f(d+tJO9O flH_$\84^ +T&5TFSD9B#ae>7)g5gYt_,9\L]>go,jr!tgjAOlRTI"3DnSX(mtXKlKgA9bD35!>>*1_6/"@)NkVS%mKFfHmqZ7`.LBR;,p=_Q^D63lt\Z("HjpNb\4^0<m%JoPS:ST9?D9YciCmG2iS5Zg<02U*Ai?nLJ76">-<L9\PU Pk?V7NZ'd]t-AZ'dlO+>U0cth)+ZG"<2g;Xc.n]L$btADVq.e"VWSL1rV>=4C=0;o8:9to5FBNO,nAm^Dh3fR1j,!M2*\*;0e(C_i,km\PAn/fJ_^5nfOMk<WIBXL);:7L3SGnnT5S]U%jo"U-,@kPHO$HN]/q:QQ:2X\Y[VBACe&4[=*FT+)Q,Vsb`6obVQ*$r$[@t-p?"I !6g6aJ% `Z@4Goep^#q!_]F?P%>8=>,d;!ZB(#TKmVTo>;U\Ckq5Y>[/b-JPf7L@tL#d6'&NBV)f],\5I-S:#ASCGF!XI3BH^=breg"m8lAAbV0k_BSC2BZQ:U5"C0Jo1GGd`1gTH&N,IhHff.UnfZTB_WfS2Zn.Gqlnj7sZS?L%R_S8m+P)f#BZ,.]jj9;Al#9I";l:4Z2-IMIZl\]4KFmiq=(t1N&BA8L[H0r[Wl; ++?AU3o.A6T)cjD()7_99M"mVd.S#"LIoicsog^EW&k?V*X_Y?j-)4AT?Jr^58IJ:!p2G/q;iNrQXTMOF=JOBfL:ZBlh"L0"PTK5Q`1p\sK0Ne9Jn[I@ P&/e<:,>J<j%XEU<-@Xbc:f(qMJ 1BQFad,.,p44t5/5r)Vq=c5(>!0k0iVd( -oVhY$&PS(>6#6D<Lr(322AeR`1Z*?O7WNHJW&_CHKa<5*h9@tn$GWmW1 F*:'A`,%sni`_trc;RL-M0soZs9N1oo7X%'D;G$;AeTt(5dm96<24-35clAp1</D+DBm6`#n>0R?@"/G;cdJJZ'kpIYjE0^W;XF)@6)ebFR5 D$<WN,Fch3(1j? <0DW?a674XLcm/TTJkg(ScO[?2nlkA6iin !4D"iL!/W.>i_h?4'XgH)kK9].eX,I+<KN?b#7CWVi/8a4R/a(4n>d 5@IUTA#m/_>^LdkKsCGg:6%?`CO-*2AhY=cAfQE:jq/LUfKS%Oe_%Ac2571+OS^:q\+JMM#DTiK$?qs2qAD?fp6Q'!4H*<07)Q`Qq/1++o)VCNW ";j<S&+-[ois:kC)MW,Ba'35Yoh1hR#"JlLPpPTXZ@Mr:fW:<S[T)tin[%D6V*KYcI=!;Y]AKQ&o]%Hl(s(E*6A#q@%S8Wdt]Ff\q9p6FEa\^GSZQ dSk`aRn!` :,\='EGl/n[+,6BK3J9OZWbV'q9&1'3;FmW`QK'?%mGGOIkX]F6\jDnTN!n=:2WnA%$?J]#P(@M97go#PRJI<sj3/aQqmt$Hi!!qKr6;?`3XP0bek6AK=q\$I,&^sNafelHaHCA]U?rX8)'P2qYUC:#I7>PMcajPaiR,"+a_3$A%YA]j5SdVR**sM9K!(V/G!#>0_l/:*MEAiXIPP&bs6%ea@Z=[;l`TqM1!o+<ca09%AQA dOF:LBY.8W=lki`rAUP0!<bk[LLFREC9P!dq`(=$lVl=Ct\Z$'lHT`EADl)FZDG('S/NZ4J#+<W5t3' VakY/I9^0;R?cc`qQdq*?C9R+3YfPmG_3;O.3QSPA2'q-8HL(m"RgelV)RW@H2!3ZrmX3h0d$<*Yq_P(sD:i,NftXn^C90g9BR!P\)&qNYte7U^BNWS;D6/15o&qtTG-H&bfsc2[oDAV\5N5RKA&[[>7mHg-YD?3m%1GS00r<P5t_Y3+jVHRR-*RLOCFA:="StiBqqsoI0fGl!CV]PeACc.%SA"gn%jmS/Fmiqq&3=X!NUBc]E%k!5nZaJ)VVX;9B+pI2fO7Fk!"Afkr05Bg&-_A<J9DYp'o8`oHdc;>;IIc<NalI7=M'^EXK Dc&\Q"P \29;7n1G`QS6=n].\*o1t(,">QW1EAK83'=;% a.Q8sA.fk2.Qcdm`,g=$CbdABJ)[&F*n')mgl`Hst,f?QW"`rU(a9([[\2Ikeb&,_"i_"r!E5\rhS6>^EK@J'=L"Lk\"A,VSWrSAki;r<'_nj>'B4%O*TQo<CR6.RE .0IUP_ngW5TZoJ]1dIAFPpgq.m)3Sm,T/j)kVtaIA7DDeF09<\^g1HsjB3jQ!3o+M$:I#"$Y)mBBNJo#Ks#],Yo4AW,l4F1rIegpDd,R<Dd<+R]d.^aApA^WoV,H(DCGGIU$II,4(A5fP;VVbG$C(Yr4$/3ic,QRIZQV`ak,"Rf_N0r))A0T)nAVr#`t$U7l&RdH,pG8g+$L#q_ 'bjF!j<s%^s$_6sII<2)F*`C=LJUsAq"rZC8%'?$DnS%Uj@Q!T*N60URM'o"ZGssBF\@aiQJpc)CM5cgc)O6Sih<!:g<7:gFgTA2bS .')se-8*&EA_ r.l&[0S/XJ\as=/KfV60Ai%,2!O@S5dF@*>1D<"\8 A J;Db)5VXGp.JEDoU&cCGK8:DqAh'DJ-@Q@9QmL9"3Vb6-P!IVl_aXc<WJ@K?a$.4=;K]6t5sE&ePgVc"+6(Wa?1W]]Q?,0/,l\AAA'$XK2,FZ(;ORP5jJ`<I+c9#A`RAKi\Y W9&Z&Ck[XP:[pf3'1Ls]#ALd.C7c nQG" >_Y`6,d<g2L/2j9ZCN@3Rg?UXpDCot0O$Dhnc6P.RX(e.#4_c>4W1#9P-[O^$-$XpP3a5TP9QapQA.3Y,>S\9VE-s%!'-:J3[>@E&RU!B^l`5[/]5NF#E)KN3iJDVli&(^APc=W;C\ts_-A DQI1G&DRaQ["gUk'[.-qf<_?7:DTEOcsA"WZVI!1DA?6jC*3"KF1dik<9ZsM!*!sIW9A]?1A3H<dr8t,XqXSo$;"tT2btf;pV#F $mi@U_#S!/F*)k1_.j090<s2%C gW+THP=kikhtj*?4nO(^_,-jl :[lbl_SlAHn]Xe[A*bGOM>`Ggn."5\R"m^cEO0nP`UXAT^:r@A=GtfQsYK QCrXn=HkrAMhY24e-qFNG/N(E?tFiAS>++fFKXh_MKkGI$_#BhA]fm7W7nL4b-3>dsLfceR=.-644QJa@%SREh[fB%lQ L2203F:Z[re0bL*j_M<nstP<:#;\VKQGLs'U:K]h&N[Vb4kQ&UYN,-D.[0S_cUkC4G1f70%nI%T&[rTG`WL'E`j:Tk.>qpjB.=$=)1F6rVgEehOOA?,8Q/AL@^'f.=D&;AFKtF1!qa38E_e4EY.Ul/.qMA-^'-L;nZ2+k<Pt&-M8'1HpRR De9',k/MIA?q;n:qXk!5bNdlG;"YX@G20Q.(djFLeZR@F)_\9*_BCp.i6smQsIXE>_!s-*Z\f?P&D9e`+T?U;X%EpP)+m_e`WaKK*S:f%.L[9Fsng43neJVmSA5VhlEhYV<4Qk/0$?7?!OIH7/%T+k;h.d?e;,Hp,FMVjL*]ZBAjbHL8e<:)#m HZC<]:3D\!gsl P%%k+#`ep.P@V8@FE;89DnX/oW*/Qleh*]5O=#eQ,h)6^XMds1%Sc?s*DXTj/F" cJ=\WI%pj;dpFa2Dbs0!g-JcCql!(t61`Lgg s3U-4*:f)@SG&dS.P5i$9[T/^ATKIBllJS$Z9-_!Y7[/`<Ao\GJT>QWbd]X9K274$"[1K.<(j;7 h=::Sm_hEn>l;kaZAnVtEV/C*f^n&At1FDY4nqJ=f=( Jnro]cA&UqH`M+Id@9h7ABJ)2&6%@#bbRJG5reK9l3ndDB]KoBnB;)/t 7QPTpk@6g(?q,eF'"rBXXI_-LqfA/cYARq0Ot?ANt95D3*f>1e'#2o*D^->`HJ(@q5E ZE%&hM'okp0R\*\MAAMoAMje-0SAU)%$\&bJ]49!njTfPEA*?AS`%2ecd)A>j'@S(Sl<W?$G-\e>8:@@?!]`;6o,$k#J,LI`T?.; DaUU9)#^nCkr,-I'/*g>QJ:O<!$Mp0#,ZU6jADjA+_#&8AT'nH pZ,:c`nBrO\QC+E4qCkZ.QgY530>l% [<1KRqcj"TD\'O&Y2<%X0(Am=7o#VXg[h9Y"@1tV5&#@--Sr.(QU.0nf]P,4MRAl7\_H7-f0 \M/l.UUg\t/jI:'Zs!r'a%^o[k8*/hA0g&Ht6L(^A6Z*l2HK$1*PAZCN5fM(G^nT\V^O";<Rt404c #tp_FVs^LleG+8!(Cn=qX<_Uk0"UClC%'`m@PrpI6jjGbBcrj9qN!#\"TWdoI-S83tjGV7B7?G8l<M:eId1JITBn\o9`$K!#/iAFG4GA/?a$`Ai'G,<7_C_fRWq`CK0S1;8IZ2OsS(?L%dABGaJ4-H'gOAB%OiiD,?0RT,cH%!tRnL2RULg(ab^X^Lg'LYXXo-'I":3*\L38B;BZH4D.Kjb`T,1$!(.3nD&geq>oobZb>;#1WeTQdB;9%t%E9PtXBsN'QkjAi_CK<1*do1HS$lVpatOaAWH4<pgIt]>`.*)7mP%gFIAo:A37TFF?Deh)B-PF)QP<'8p>A-D)\GLG+o_>+O*YepW=P[b]n++Sbn)0J?@ehKoD?VSmHiK++E\;$,#?,j#Ks2a!c3_R=K-DJ7.N,8aJ(gIfsX3c2)r]W)=@e:!-CDW`AEM-UBa7/MCc\GVGa"C+pN=B6Tc)b-jcR)?`?ljG1'4XU/7j#qFqg8><qtKJnQ0f%JsU=-b)&P>@MmXD;,%mni&W6U-9%.#A#J1)j6S:qe:7HNrN9f00@"=@g+o'=bA(LB(#M2Q0#(15*,#hI=0ei7nsbYW?rl0Jh2_'m9.CLpb2f^DLI4'h;kDoen2D%[njMd*]Brq',GS%4Ti'&lri]L[^1,llHKBI#LA_]"5F,^ .G&,@/ATTj67<&QA;A\[C5bKT>p$*d"-I?X+RFd=Pcm8WOk-O(+j[0inG64`nWU)>UX2K+8r9]8s)NXL'5L)Tkn/i>P\UKVb H-#/$Rk`J%S<Psi0%O-NnsM1Oji&rEJ AH8Ie*Anj;:/?aPA?,q+"rGam:f^@#Yb>ma#PO/=H+gBY"1PWQ]-$?O/Xn"k09lk-i+t$&aEV!:tgY?5>k?Q"f9#HmnZK!Tt$5Yck7V3c?ngJ7sn4L8'kW[U7CVAjhCb`F/Q<RU*3?kSQO83c!G]=76=C6OENoL"J>q/6rP6-eIQ[RNfOihrr%[ta3RXVhh2Nj4A2Wd&<;sYQZXpo+4Qgaocf]b 34B;59\?%Zp_8TBbO/`4g2lAm'H/2%9/;eP<peJ]:)M'fXA(+Eg^cAU/Js6CN_!+1a'\8nW=XQ6T%"^)&U >-0.U`[,SOYJ:SVE][itH,RW"PbZ!MgHV4%[&-9LQS^O\C?B_YL%W r1/\2l`r5r-eTKc7:jRFI[3k(Bdbk5$3E'NGeg#!Y),<%'`Q+$Zh>N! ?K0:2:H`P`H1mq9kG+',b]^`-TJ6!VDE kXq7ODPC'db<HTc8Y \?'3<nWDGj46c%C[=8_PPcC:H@aUJQ@jc,/e5i)MRWBH) 0] jf3\+UfB'Ks#WP"QB0i6g0Upn(Q-a:n)^^o\sh<eGA^24 "`@[8;.F6FtXr\N=5bKpt!>?CLLWB<58:Aa3G$!YP9>FaE6>YRi08]PTC*GQgeXpnS9djJ\/8B6\i^40"ZC=e[O:-^5'F#3B^MlD(j,SCA\OLt0@bK:_6]i^3/QrapY0OcsfO4F-h(n\FqE5JT[?s?qF._HG JiHBZ`;*b#m]=(2%96l#.!rYe4((6K>DN;40gp@=iV_4=@33s=!+%_Q"N.7W)Hb[_/Kfh_gAKBL*NtJ-_!U(ms5KnL`.37@`C"sO-R#rNf25)WKiB`CM'7FJ,!b9#&+:J-6pb52+F[XBQN4WZG1fJS!Z*s,JmA6[KV`g+q6pq4EAc*5!WA80f_Q[>0]2*[tA<G$Aci\tYO%Z?37[Xl-8)9(<'F7r'lO"^*"rf#h1Vi#6=TtDmi0@#5D<ebV8SZE/S9Tc*,b4e"ODGFVLO8G=bO((lg##k$-8A<9-VYbi6Ai"OJ/Ec9qc!(_P2So@aOB=/jOML8m!:;+\/;LDeA&:JRrA'h/0:$)`grlU5^7#[4)Cl1H3'k/Cs-+dDQ<i'(/9(320V0:NpUH;)Uh0>3?=^Am`GiK"R:N7*]<"c4# ;gZsp:3<69dbiHc7CG=Gr1Kgr(rt$,e7;.(oA3C1AfXY`q6pO0%rB!M+a_AD4Pj46.O2mI@7n/Q<[@,n@t5C':,T?AN:^[P57m(nl+Ud4el*[,M2jn5!(?2'M\S*7n(EK$TqA?THdj*g"?.YM3F'\atVAkckL:E;CKEA0_!dMc3n)h\Or^A'YiLPW&I3=NL.Y+B@tATD6MJV]=j[F8N'W*nA'hWpm(^(,*p.[BYnF84Bk??ZfX7(/i3_Aj=fKl/N&#kIi8dIAM8Q5Z%.Q2A"KfX/or\San76C0)s&Dlc!MY_R+-f4A.H;'$H>os4rf+#>f;'9)t7KAqc4nj+cB9)%]UrV6P\pS abT$k>HB YaIYN]j3r[RM;I&#`T-ADV52bqOo->D'X,3R3:=f/$Le%Q#g7qb)2[]^mJ<7+%N%%!`#A'L!tQ-s?Ri??bX:etWR_)R:."<%g2VUQEe(&'H%/4k0eD,Q%g9+ %O9\0Jam:+d5.aE+<Z-D<9F9`_HI<hK$B9r<]&CT,odGn,&_;2sAL\^CniFnAEn*&8FG9'87D" I0OPOhWIHT<GB%N"An(M6OUjJ>):XrnrDCZ)J1MO&=)5G@<iNYD%8@<GlIoM>`bQS[Hn#E)N_Y$j'^N[&!^N.KL!^YXKH6=JRr?)Qk$_c+N(38A=_BrTSJLh;s].,D^-)U]H!*80l@_XA]<'iCPF$#ZGM'2,JWo=MP'&Y?HlMKd;Q7L<1#U(3f%8"iSNFfh.iFXTSAJQFgYp6\B)[TI)]N\ZNti]8+$OKoF=eI"AhS.VcC?E+7I1IoFV+R`]dJqfrF#@?01]/QVYk!n2aiq3,RWOJ.d!VR&h.RRm5"C1-#hSAI1NdXhq'b.MAP#YF"Zs`R+Uq8tV[KQs!bOlAG35odc0aHh=3qirWA<ON^=YW:_T6+CG;qT(<HF>d"?Z6I^.4lb^XHM"'X4E=[YDbS%I9pR[.J"kY6H,)2^Gk-K9SiUN"o/S-;0_sgoNSsh+kp.GAX=J5,E>\l'$. LGU$=Q$Q..^_Y%gf<X<cAI`=IC+,aGb*3U4Mc3k@gh58D<DZdm(+Doc1<UYo.2a7XCP^0=7Y+=F2s>5ft@6)hX;6SSVD(<tbBW8`MVq:;(/-A91'9P4<Q6ss`87+P$@7]V8ff-kaY!*ib'9>2ES,cA,i9;&9p;U`sirQZ[_n_QP/,lBIKpaEs9=#l+*n=cJ&3bto9DC9UN%ZWiW?l>TE26L`D%lcqQ:U_Cf*5d+3%Il0k9>Y7D[r`#pPm[8,.]EiKIIVY:jI*@tNioeS-plYcaZ3YKc^3rUr8kS$a1:Ulll&Kbcs8a)cCXO.n_/?DKneYMB_AlA"giW'AkkjhA$5#Fqo%4khT_2ABAA^QI 0JT>b/E`r!bNVVXXNG!.*]i!PVfh]MT q@rt@:%d3mG8*qq b<17hcTcU+Rk ]d#.Aj0:Sgh)R^:MN6o[R&2i,+GdVdj-0-QIngWG;N`$DBX]l)K0%n;3C)A6$N:Uqp^=2(XBb!]&AS;Y1-;)IAY(o*3,"JEAmOX O/R`(q>=0P(3`rSP?:`mR3N-#En].K6e/h>Qf6[>WT"*pK0=6cMAUgL/hR=e(%Gg"nED KptIn1S_8P(ab9M?RY#^]G\3s(^qcq-6E_K.]hRDiM"sEU\ UWV\4Q7h;[2V9Z+dj!(E+W/Fl//UFb\`QLN%>YdO90@4O96K;_:M/4)W*Kj2e,QZXo!Xq(l@6<'+L=c_?,B3VA2AS?AfU<CkU%`V8&r'fnT  o4;XCg3cRmNp&XF`B/3F&(kD!Q)b.bi qO+=B8G,d1j@Gq&f9NOA60V4'm1_A!?Q4AXINT%di=,ih8D0Ts/i(!'g4/[/c/hN+d.+aUOOKGDD_\lA%-C8e%OO`91bt=gb<`2U'^K,Ujco)rreIN&b`HHJJ*],A$ 9d'VUI5gSTJmoMaidJlfq$3?+/1N> R`X js9,kLt3$GCS%21rQ9seO!e&@;3AVdl)&3s@HCfAj:H8l,UUE^*b!0Q-AL8l\:^#2+ $KLAh&@C[(Sit(tV27A*6r<X=`>lR=>7>6dM5hHA8AXh](F(==jB"mT&mA],Z#nU(50e\=8lQj[Y3d\N/XQFsHs<bNM/_:Yd+-iY2O_$QG=EBqmg,[LGP[d0cAhd_aXZ]0+TY<K]oVr1+@<?FQ8cjK<b3 ZaTEn8A./T>T4&`tY'*H)m!ZR[$T<V99:HA[%h_>?^Vdp,RI;oJVfKp::cpH:\POOh>7Ye^I1aW_BoEl'B@cj'pk]]3EcShAoPXg7jqHI6!KlVl(kb1"]6W?7c>Gg!,;<l2Z=&@QQ2CACig"q!/F`=8_)*e&Lo(4f%7la3F=trN7i95L2$q.@5t !dO@1adiG7"h:7VA7j5m3R+6_k-6hBOgIi0st[<9b4O1q=HOfJk7"TPdB:0NnUf5hg?HUhOO*[9j\=QH6J!fe/f1F/G=O;A*qHa4\%A6B*oFLtVLhNZ,=k'opTa`ao0,]onfJC"`K,CSp6K50ID$C2'A#,)rQi" `bdXVd^7L@5GZf\['!kXp'Zt$9nfEi6$=&C?/7g2$gr58BRQ=*#j8W+J!*,GO`\`Bh<3gP>m4<]'.XQ[DcUA.9/UnWfWBf`-%DTS&g*O#NsfW9P#Ags_HW'$%0RpUZG&kK45VaCW@;7TSA4,[Zt,,-@b18*@BY< ,1.Z_nlhV;:SXo&TpqJGWb99j^lX^,qY>%dSGtf)M'FgMW,*c27@0]ACL4fH4HH4rejDXr_T@0IA+LW K2nA^0ZTG:[B.s5J`0 ih'!10=[:OtA*W>8Qin#'1K,OrS-,1GT!,5,+2EM("!k9RAD=M`+p";q!S76o79;Ii7g"WD^DOT$k4X7E&-mZj&GfkZa sl:G;(05#jSq1Fm"Ym9q 5K!U.G%_@Eh]=,M(c5G[+:l-/)U,)Sl*%A\$3rW$X;AOXhAX'sf*7DBTi>9skJ%GQiYSk');4L"tMK<\(HVF%E&,coajVoUP^V_T5?-!MIkCnGC-m(2`<f  :ZE/XX1XY0A4U^c,f9qs.m`cpdkX!fH*:og;q@KEW(*enVX&$/Cl^' /\EU+NHe!t+I1#"(-h1$!* Nrg/^XG%AWrVIM]]5AW0i$n.r=#OS:E;gk@>mBGWj7(5T?(9AQ )0tYgAo?&:U=Bm"7ia[?PC>0)_qWWUU>/jP(q)+OWn6LTW \gfa>^kXsO^qQlD33@qAUseAl> "FdoEpAY7jtf1mJNj0=!/sSpBU[Ghs\q4j0abhL,A"f,4U:]21a*5!N$p$&9<Q1Z-8$jrGkd6dK+aY`T8V> ]0A;EOf67e\04b.-+3d].\mAkfdhC=@.ZUgng!9dqF$7R;l7)&lE&mjN$/"E,<GiEZd?i61=hFVp<qPGX(j%-5*,3&g=&A@/m=9Ai,RaZB/R>MAsGAQY<4&AF'[s:lG JT&lO=[ck6$$TQl*B@ViB#gPRaNF:oKs?GHXm$91<\D+J#AScG\fPC_!D:5iHm0QoU3aUL? 3WB>`C]7QB]pQE,B#!]CGCK66p%EG6[8AW@"*Dm<8H2#(:Fgtae4#<t,!W'TBsO,"ns&9&'(a0%.jNX@92"p[_l=r6*A>!&CAV*?!A,>/5j<k@nW9CL 2dD!!.#VUC&X&+Q@&+KMm.#oSInWX/I@`g)4Mh[f P+X4sL,#=rG BAaPKtP)`Tao!aE^_Neqd^_@P1[%haI*`)<.sid4>()QJid19Wap'025k,sB(-1NVt\KAlm;/6lnQ'=$EoDl(A!I^6?0JVOO@t5Xj6a]glpg`Kb$pAVC`$Z`%*t4Sr^+3%CT?H'Q8:_C9q$qeDB2G@&NAN?3"2ct2!R`J`_Rdk<[2?#'4I-&eWNbEcH5O^A<,45kbAJTng5cjY3a$@#"7D>DgbL_oY[>2N<37$)A1o52B\fR mdT>'igh2Ij)VtGBU\6;<?g$APIHf EQd)f%VgQ0 &cdkjm\W@4KrXW09na.=?s?6\fF8f#<A5dDVV:peYQf+2i`FH2l+5VNKe+JM2i>d6C"t`L5eqC[KAaP4XPLQKYB?Dhmo?,Ul3(f]AdVF6E,#4?N;@+d[fAH`GcpAl j %m>5q\/=_HrDnj(S=l)gqNXXt5i3tO<G++Yp&["Ds2GdOLaD%Y2sBA*CF599bLj4b))R(*Z8_Q'4A.AQH0RCA3*(;3i"Rb_.QK&$mp56-qQftE;!`5[P"Kgen1K9$;MKLiqCn]Gqf2r5]OUOsM3krBF2=)d5-*1AWrcB.=cQ1W;g+C@RNYI6k6e3Y&rW6XnlOp\OeD:-Kf1:;2HiN`_97?S(,@I6saUZOCbQ,K!5MY!>l$/3P!5&dINtg7XbOR)ngTV^`f1!#/<A86kXZ,?pIg#5>[-;Jp<RTNAm<5KdL)UHC'0)QMpcX631'k($pk^g?nX3\]GMF\g!:C7Hq\="A61_\obIP)fn@S6LR"SiA//eIY%2on`7*ER_3&nS6\[+?a8i7RC 'nACe9sCGZ0\r+A="S<W,!PAd-AABAk'KW@qrm%FtB.R1hibc*@\W=DqaRY?Hp:(PX[*`N8NBGr! 7T\(:Yc(A5\FN+S$(\7'=Z^_^m;L04$/r1D.*%C`&4.Djr<AU<.0FoGF*+<`Jfqlc%4Y?;=$3T*.Lt%F+J;BR%LD1g[\%"F:Ao7A='QA41,ArGXHZ#9 Yr]DnmUGYqH;Z*A5(n0M&o[@"(hC*Y;H AD_J4"lNU*DbhD^*(M11@4bY\)$G]Nt\FYG;>P?kH;W-QAb*iqI'Zcp@Q\P?$%*qX,Lnj4/YT@1Am[Q':WYY[s-Wm;Y`*n ]cmojAboKS"20Coaf1"(Q08XsBeVUMLN`B]so<]%1n_H]9l\j%4)-A;0%4o7H/:W,^`T.YXmMHjQ64\]M#_NG9q<=Kf;(,=f`l%Fi4YL)/D[Q1lCJ1Vq6kpFhBq$4TAVY%<Y^-53WF9hM9bpa.b p*O4odJkj<!lj_E\^gAq"95Rpb>%Jf$@9VtfOQbhA%%AbJ-$@/Tgf#p9ndpjVhjT:L0e`lJABr5<-&Mo/+m9:.)>SZ*%LXfiJLOT2g)HM,+D[U=7hAO:oLej8=eg7#`TK/@FFm8/l M"oXQAgoEK(]IfTt16t]=Cc9t1RKc+1B9ZHU9B+Xi:j^Mdh;3QkL42'MUp$ke?IdFVP@'>-W[PqLNLQ>P<Tm0gJL0NN2dE3]WANDlOI]IK]R?Z0MA7E_`n!UR<d*>[P8Y-,ZtJ.2rlLo:pb1AXoKt^Q<k/o p"m\I2'A[20^#8Zc%]6hj@_AEY^S2:qA`Y`[g1NCYfh.Qd\(b.6.j(/k2;` _3"c_:?H%CE :Z#< .>l]OTo/5DMrp_DDiAi#Aj0];_#:9LB]2%Fd4ni(*BrD=7D*MfeX"aF*0o]Tb<4mN;!J"N#g.Z<CR$@HhB=/HP'T>'8p>8AAqrY0< d*PTA_9JA6<^^cW(E2g_,.O]B8XR<cQ]fAXEb6=-"W^IKSRoL!I5A?ZYh))#FZoa(ir.?JaCrCl;SQ`5alDo:jO<0Xj[o0^=YhC))"GeL-I.c.0>Hc9 g_1A)f(*o^=.TQqIGp1>6[Hhbk"I"rJ'D3Gs2*IA*['9aiT%<#+UB@_Y!IL/`k: GSk7YW[">kK=YP[aj8^X<`&?;*189@+<op[&I@3[)%dH> 5A!';)=k!n@&>K 99BErIqF^-HYH(tsdRoAD,-B>2K]@SkUBhFWd7/7L>ABL-6[Ai_!!X9khq_IRcMM<_$/Y]rBa@t+ab/`maX2JBXqApH<N!\6%Krd=DW]&Tr#r@ItH_3P5d+f[rBa:!S0Y)<]<X)A3WT#Km`-9]%sePdTAeY'[H)@#MkfcG4/j#aV^t;G_$e=Kps8\pSA%s2^1@3\V.qp:U\N<CYZW>G[0>sq@o]A-"EY7f&\VPn)A(%H65WEo.?d>CJBMnB/sEDOU&6_OtY,.)QE?j-`;qF[MQN?[%l<W;,YP0BjF/V4Oj$#VYP.e6kpTB[:hNYeNa8D<VG6@J=o?d2A8rt4^O)LR3mnUWGH:OYCP9)e7;gjLKJKN`2a!M5jS5_!b3/JKcHZm8TJkeLA(OQg+M_&SeI:h5+rM3&cHs[#AZm'C(Hk.73t3!@bhUjUj*b%g6k:d\2K*b5EC^-6FkF $3,<h;-lZMs;d:\2<DD<pX&@+<s1ai L]]LM8N[E>(8M6)6(50.^^!8!GPGer__c-dA:TU]Jd)K\ oC+,0tIjPR9:Y&jMEk+E'p<W%IQJ=2g?/tK'0f.fIsHECsBOttGn1VIjb*LUh^h4J4^KiK0';thTCtSt:L8ke(?cO7AH3^\G,4*Kr)aOR;SE1ECNp2W"E$m(/BQr1(^kmZ<X%hLKID.XQ05DT&&?RN./Q"!HHs^N/ `F=09o'*i]o<J,Xbr3$`n&XC[tt0C3Z*9$SPo:NnSBqb4W[/E6:lKc[lK<pMr> Z?-S?>Mb6eb3(j[+8^-Il=2<#/OH2hT0k>Z0[[ssS% jc&jJDqIj05q 2H)_4:tIeX,9O#k<@3j_kI(\mG`MJRJ&lq6Rlbn(Z(iXCLs3W=D`7O=%qE/a3L@rF,2 LHMlOd/+O85Kf%FH:Z5th-l%DNoKcPk6qHA0 SR`ng%p*^tf^hl;pQaHdRsaNiPIa%H$Fj['!_2IARV6nks2EqA$2Fg)]/dGf?,7HMD)#;=[es(W=gOOrQc%Afp+'Mh<1#3mV71a0a`R(b0BEm%<ITiA8Q:$rl"^ QM_0(\Lf_X6AnUU$*:JH)p-cAf`,-<+k@YnA`6HR8DZi$1o=h<gVr?=26Om?E=KWiN1R-9+clIIYmac58&3)(78U?U4#hKm!l-/OWFWVH>H1H-j-YNWd338:"\d khVYX$npa2m\'p,$/C/,iPi<dfr[b0o%M<2`22AbjVB!SC6dJ.m]"159!!nroqoeTOcQ).snY%++HmPN#:9,Wb`@ds+R5#V<VFS0qrRh>jo\,'$+)$VA>fX(BI=5L$Aq9U3j6gQ#&A1,V]="AX["74tC$$h:@12L8BIYH#2`h>#p)8,PeYJR%Ji?f,8aH!N<j)5NT/k)!^[2mPGL_P9t%+RYM)K6[clBeL:mbt6f]]e\,J+_@s7+@-]3YF JY2hM2UW`!Mh\Hs# 1DU#VgAa'iFIh.&5.7;]3AG^fmD k;A9*?aS20KsbA+GL29'5A ZB=iAkm%i.dN90(ifXAdf,WF*Kechl>6oQ)I%_d[+0aE$a--fXo"o?P-J/5T4&& Q]@ZH<1hindE]&N?!fBjUs Nt6>.(*Il"`3bH2M;,X[_-tGAY-or<3<e[>jPBii^BRB6e\_]%/='Qm?YO=BmQ;\o>6CX<n8r_B7AC@:]k6$ GrWW6iVAMRTPLh`%S-PcHpe:lYHME/F<g-J^!DOFNeZj%b5$To^!)6(5LbImkHQQiK&PIc^biOj,l1(KT`dl!:A*D*V@&g.e9sJGkL%MZb-:+;=TqSllktIft,^X]W7)#4eirn Er?DQ^kBH:*l@LG6O,sI-:s!XZE\B%HfM]r`65f"#U^" &q/VYkjtAL,,=`;>b _jV-p9Gi32@">$<__8(mV-2onU;SI4D1 @+7H%d<Xn&4(>3Na;"0MRd( Ip'GR;Y9-U+%tN;VZVe!C ;DKo"FH69j$OM:8![&VrKWlmb`m )W_hT7m1Ki"lERR )P 7Roe/E5T+Yr6 aF/*4\VFg?),8H'0<19moRd.P:>;:37Eq)PLcE(m+c2_i`L9Et+a[%QA#dhT20^;fq4Pi.b+dYh.fnaQ`K&_s$;7+2DK=G2sBY=Q]D05AOSgkW;gMpJk]/^e_8Y'HTa@hQ_4 F4k[Q.X.gH9,Z]MBh:@O,%m1<&&%q87meWipq8<R?WeZ$;XV!A$\(`Bs?a'Eb-XM_t7h.Xc`;;*r(#4S$n&DX^9::W&m6ZU"&$=cq=?t:U5`VA"noeH2]01.mh2"@;Ahd7f8<rJ;jA.mhBYQ&ARR)0Y/W#(+X CDpTAmf)-\+qTo*X+i8:YP[tC#4%0S5jnpGl20<,1)o3Cg0\honDGkW#th^_a?cJ`1]$A2'dis/rfTk?LeHHnqh!^AZY>,BTSRh1jn2Tg]tJPjU4(J]$PGCb!jCYjt(=e51DQ:%4ce_e#61K!brrMtO0K^)Uc+qA:"bj:P0d-9HL2oj%72HJGJ^@Q)m7A(eMC"AM3CHg-@6plUUiJ-$M]0V!>^E?\M`Apcf&@YKq33(Xm]O`:ARIe@QAfsF!.QnrZ1"11A;ioWci%j3rETcn.?8[-b!^Am39b''D _kt,;D&^\moFpEbaFQk.iL0gsh!7`g=!=<aHm`0!SC=p\k;sX6Qhr)?]4U5j>Z2mIS/Xi%A,sJQnE^o"642#0$%?"&5of9d<..7 $![*BQ#DhFerH@#oL*K2[oPr=8.pr>,Y%l=Aqar\;<V.n(['6@5QItd[Xrn"k=E4jr_)A+N=[#Z`T[FALCVZXqm0C;DqSm),[F1/EV?kQ7U;M?8&]/ALe.3_ABnA22V%g?\p24; TQpW/e$Q;r<[0_6]d)8m,ZWo1sk36>_UVZ]YBDO[IjF*M^YB;>ec<Fl5J6r]dY?38)75?9eA?(^ZVM186JKCpO&gg,oX3C9OrB'?lR40s\97q+kpUMd&(=q3,L&b0)\FQ*A`r85d4AJ@.Ih#*VSXa%2D)/]Q4S-t.gN_!D&CdF)M]U'O!5eVR@(7Qt1jA:5e(QQ*Cp56"jIXl*U"8eA5&47p6[ZE58*c9VN$9+'n_2P<m[n@M"qFII*C !b6UM$G49sAs6&R,8%iR,9(PZl;L_+hXd<[?6T,:'r,P'Gp Z9 0/[D.((-Zbd7^fAAK"'5A=A<=V!dUic$<IGaXIjNJhCC`]O'A10Xpml68Z2L`fUk"Y;A[iTM$W\n$*[Jj((A12]cZ-0W$%gO,5Sbie4L-pmn4b:fn.bI)KhkO]&Lf3$UiPm;'^(LeLW(EAh\m/"LH0*]9#bk rpeJ(,L<q4/H&'LiBY&4B HL]@/dr#+!2@J"$2q?3sG4`,L+0\K.NC-JpU9VIs'.'';r<3skO&Vn;>Z@OO`!t#!jV7C%;bAtf%:gnfgDhkb"B=_pYmF6%WE@_2gV9-+<$cCNL]oAaM&5)m.GrSno/+>Q:^f&POh#KblmSf`3WtZo8.\TS[.6GLB+a6"%m3m38>n@KU\K90Aqn5j+,`"\F9Ya%\@qpK=Sa<<G"cLADD(a@]3Lr6g:EXR5AL4@QVB0a=3*oH6U+haOdOd/rANcqBd,AecrR8s$Hpq(^K(RlcjT,(T`>T!33fYi=[2jmA,/$ r0a.C".=aZK@q$$ Ecg_kl.5^Q'Se;=/UT.age >g3km P9- 2,^RpC[q?9r[:m GcQJ/.M$OO&b.r! /X b.[_\moe/C-kSpon'7eK.g\Apt]612!=B7BS+)h*MY.9Y5Nq'5l\?%6[Np&!o\7!B)6]O#nDP,MJ-/F4PKCL46[EXg->I`nje*+1EJQ4_Z!W?98AD0t">@J1S4" 6DnV-?T*r"MH`!$Ec6VU)2gH##7P !/.Z';K8R1Ns/$0A10KQ9RTd/nel7AndJRfEAf24+#[C/c,WeEn4/Ws ALN+QJ!Q5;ib-Ucl5>O\%0//.fFi\S,c)%,K!,Y_6n0^nD5k\;nmbSLf_l <Yf.cs"o#gAZhK'SBW1-'&q:@-p65<UJneQmSnJ E`Kpe>!GQ_&Uo!mN:kRl\=8_8HQLX1TaOANa/?(8NtU#i<^T!&ABOS9:^:PULc"ghLa6<9ms-QL'E0UWUbYIQ<.hIbP]JA8qgb17+l)shX(Lt8D.8?d+tq$Ym3bGk9Ng(Jq nOlf=C#O9+Q:k^cE=,]+c^T2UY$GmPqRK:1qdH<aT]JNrO'"d/ )b+:<1q0pfm(5OVCT^nZ@IRl!VErQGt\WPB\):iCc/%5so!/-VtIs3\#ab(6lr'h8nQ&.qX],[iCNCa. jU*F,^Z5O&tB.ISo8eAPDW121PX!5k0/:qc-d44p&W2B(0-N1=HPA[AF,8 @.]>&eH\b%N#0d#%P=%5Y@pUa(m3J=^.OU97naP_H^Q6=X5VgnEB\Rc\R]_rPPF +CjPJNLVfJ(^M9:L>C:RaAblU+[7UAfQHWP+q.`rT,PLWD)<8PB LH@<*lanqM=l/.\OkXJEFFV0tA#2'o,Bt7#PZ:bb3q0To=)S%N&rL30f.Id4o,3Ie1Vt= '^'3'^i<t"L6@j(E[['tK""llm2MR?0j[#c>9psXE\M"MS\,?S-Z nG8[C&V5TMabH4XVi9Gb.GMCP"D*ma7(#;nIn(WfG*hp;_2HsUF#GUd#<XMq97(.YXN*1rE*][VJWqlFb-0KSd!09$U09:/D4!Ft%O$Z5SPU;kAXL8qLhn$_3XJW6%%r8_rg"U+jf2!/mriPrh\a:jHC[2+NT&[<m:]Wj.ESA2Eal!GRDOS5N_K*<"lrt :5mk4!]@^thj3&Uq)qKf#tQN$=cY[p`=.cs+3ti+iEAl qgi; Xn7_>=&7XL`[sVMi%j2)/-:->AUAHiQE"GXQfp5Z^@TKQ)YJ3E,)!AFb\IW#ETD$NZ(<;)L4D#Lofa=)(G7QR MNZ'[)?*"K f3teIh<pD;<"p#IVEMj>HA&A+Z;gN(2Db^A,M9Ak7 92o5EOtEhe%H4AC">Bob^kO_ o2)`2'1Y81je?]k_Pn]cY&sg\pb?c]"_ERiNa(5Ih$?aj`>or.b 9ef3`lX+^WpEDP"sAK7E`R?t*R]""hf\a.5ch9@FNE/k`-d$lO4,S"PLKkFo6pmpNX?-!.fN,?rMeIA5;^:m5AKA3h=<m6>XqIRgrkS!XW/W]RtKDUVtY?/Hg% ^A_#tU`%HI7`O;:=fi;CO]t&+=cWkkO= qW<&>Gn4DbX%WG^@LMiOA:DM?F_noP<t,j[ci`IS"?)HYV1_7b=BKZ\Escm41 LQdjItR?ssdT.2)$5i0RD2TVbC:WXR+hi*ACQk_'L:nb.k^<E^#""<C(SJED(p'[lkI@SXIs<=LPV#7' 1SgT=k#:QKgVs-aZ?=Qe+1AUFt\Lj9tdW8qWfBU6WHQsicOFOPVf.JDpnQER\4CA&D"]mt?3E"*'#M0sZN?s$TXXmsA]W0(`Qdnm,r5`73\UY&_qkm7>0[ti4p=eb=jUlQr-%?=tI_*h;j,FGg6n'[1+/YL2e%XQ%5Za?H1 FijKT=bQnh)Y,L5jJ'i(CiWe@k V3I(3\..UG^D,1c$8'^E"d1&OPb3+b;9'"4XIGCYW"3rc@7dn!lHr2NVI#-@GlePX,B^-/%GM_?AWi>=UO42JZtbN[=hB:__5lCt+\W_,4ABdQ,*aU V]ZJ8>7g\=L>KWe>'!C?6+Z)-0jRE&CA-Rps5K(70Sl1roE&LBrla.XhSmI\UtL1mcQ8be+cl4S+-aTsWbdr#fJIVl37Ap$.$"jJ;B'nQGQWIXlTh:(\9L1\kq'h3B9nm5h?D0F6"mHe:8WfR,:FZ`?B:Ls;/A *\FIk_&W!4'B[q=eqCG O74/*A)T;>1s$\fnot$3M/YYiY]U*S2808n3Qfk!F=@lZ=D(\N6ZeFj+6"g!$.Q,J*0,IO@Xc0m+/P )6J-K_8@A,(]XdT]DQ5NdUq)2]a ARkg"jCl.Chf?;X+#Pf4UtXtT_%I$L7&;t.4dr3A^eWFCM(l0]BHnG"r<_ ]3+&RcIbb4/sFEg=Jlo  ZO+@;_]qG09Pf/iN+o*njqQ*]V6NkkH=o).iL/N(eaS[;Fm37b]/hhD9e)Akf;iWg:Y@#=RI`ke$N(M8/Vh[ih9YeB/kE/]6ISo:h>t4PVNP#d/I0jN]q0-]U0)5RK/B8E\ D6.O$J"^tm">HrScj`3pl/G<h+mG%\Ki<IEE/JV4TQ'`mhlkVfaC<QR4N^RSm4gmll`k(!a<TLI^asG2@/jAlO^/YkP k#mSZi7%9]#lrDF""F=qMYIA3jq+mIH-jcd0Pos2U^.kTlHEd#DQ:I0G3=:Ae"C$9-N4UJ&7<+X?QbRl[Fa1@50hoPFmXdG>2JHQ[&VaN/R2qUiXES^'\*L5AIV9;I/Kj>@m[_tl7LZ"K_V*9_:toSt`Jb&HKZ59Jd)M.U=2L*MK#RK]D+k_1O \rN$SjGgbPH6c4q&9<i!ih]RItn$p"i$>40efHh`_6pfr<`;mZ!+'%QF #Z"NL;b2tObIKb,oX_<]5?L:4H@.:^?Yr1N0XKrflHFe08O8iAoC&%_]5 rGLQ:;+];W-d5Xd\m@cMfo]n$$nbFR$D=!*sFI9g=t:UA9pGhX;Z_"G-j[XieTA@N8=8)$VV R#seSQ/-OO1g@ho:05*ZgY?=F$L$8FZ7isK[`M[P"#r9.8ij22-VnZmCmT;Zkg]fT_D= kCt`_MU#4HfD)7#QWf8 nfI<M>KPKFK$lS=$n!\5YB)*/2<)1iAU2"8;OGU*M*j%A `i?USbJHUGmrenT3\=<k-J23`n `r\71d3Z3qp<;*oA2Vh,rd2A5/0%BM18]8j_!QkDN#6oTX?E9E?bcPpA$A*VO!nd3?Apg60\[o"++YAJEYigSs'(p9adY[0>#]A3NM$AnIAo J9E];p^10fG?g./pNe&$.o>&o>1eI/e &n^0m'Jc8eYdG*AX4lLWg9eAJ/d5;Kh-T'O%I\0)\("66bIG"5+2D@,C*tf#)_]ElQom_j%<o`DK^.B)o;YAKRjCPAkAko>%ndqP2i]esMMcetM<`?5+P>K\?9?A=$*OQ#UA]\b[o+diY#>"0g8S]475sOa,-^)"nRcF+)ALo_FpEA,+/j/5!/4pR l<^g,NCj)eD]OW,-T93p+T<*e++H.#Y=/<GSn%r:Aqgh`.0#8 BOHC8U+\%(:AK%-L1aK?bT-dr7I2]j^Af*tf;=-Yr`qNJ,I'Or\&]G4$A5cs(MR^mL.dtc:69/(grAXFK5QC#_I+#pZQJ[W]VjE5tI9P?&tbRD*90"4UQ_9"Lb@-dTB&0VH"F\8i hB00'plbGFAeEn43<iE'+b-9C,,%#87tB*4.8@aA=Pt!66AEXo`/9n/M_\q4$\25!@_]0b?;VhNCVI$d,fZB jG'N:]+P7&*l3d16IQRhlDaimVYgCER^8"UpmE!9#X:;NJB^Y %16FGrJC8Hd[)EA2?[InP)Y/B/d>HAmhBtKs!7jc`pf6kV1aEA( 5B]9KBeVop.NV(:%GT.b.Fe`RcrX$-]aYZn$m@4t`7n[GVNm=i`0sP_$[;,2q=_4QW @bTWV`dCb8<^hcrBaqNB59ERMDEP[ps"4lRM0R<50k>osK$U0s's3A_n`1]6igsA1W1PiqsF3X'ccZ/9AO,YBP%m]q7N&+Vbcbr8_b7X8&n<3mbD/."]38%>p=Y!s1PhSV5ld+qO2oK/t"D<d"fSaGINFrNBLZ+(hpEA7[:J>2mgS)r="TmFF0^5 49)qG-GBn/k X`[J,nI/.>Wf,Cm'mI7B9\PX=.J<scG*mj/ 'jAY$$E rJ_ DTqPA80t"Tl_b6e[M:%-b)=AT7k`!+;t\+2?k4fge$6R+NXa-ElZr4L1K%%Co-\L)-ZIM2hr+<]qaE(68L[)KRlcf.Zd&elS6l `rPBO= $2Jm]>]00CBkj)I<X<dEaVT66!,Y0P+3qG"9<0>oSG%isn6.K`cS4.rX-c#`.IPfP:I2Zo3'F5Ybo7Q4.24%+:1Z#CiiK(Mf9,>VBh'qphp%]56afof\X;UXnqL5&qT*f?%g2RT5AL R $j!.baUTI57,H7"[m:A0g;KjN,g9X%4bZl,f=nQ6.r;$'2=('\pb5&1hAfB"A1!F2!Ig>M5`Si;dk' Larm2<:[GRk%D6WCL_%K*to=+]RhCCqb(\EZE#.XU\geYpA]Q-S\Z24Pf(.FI9NopAptQ_94Fm#:kFBj;DW'K$a3tAnF3#oY<%EEiskpRq-"q_sPeHPIZ]O7E5E40TMV q3kU MNVRlRYRWI?tLlsb!A&-ZQ2Q0:j'AnA^NC*_N#Knf%+RO6EWS5b&s+hp9n7Jjt`NBHoTa5>*$C=q5=Zt[*jhRQRYX^#NaPfE;WB>NYk'PELnsn5.a N(8QWAa@VpQYUMO."U_U'j7XFVr]T ?Pk[HDbi6$Y8)8Jm8ahPI^3]$lLe<D&NgI!1G.pc,)kDg$2j 7GT:`R?IH$iW!Aaf$m=.@[CCZRhk$aMoISYKIjm]T"(VFbr"pre5>Rte_fA7VA.._H-GcAtMsC%$k&Er5QY>] $eLqENb)rRA&]"L^!0p dUK!l1NUh9N\@1rS1MiGSN4r&B\Y59U38)E+C:[(=bi)ieLR?jTRY;6,f%A#^(qC%j&2:[bDN<mEW&l5Qg'W YR2AX cRi/iA;oMJ!%^Bm%\hBaqE>:o*thZI,HHk7`?o'WbA=$TfE<g?EX"(.Il&HEg+E+3G+/L*>nGj3&^@<MrOK8LZsF/ie %+87>agOQJcpQ-[)W?IgsX<csriB-(A>O4Yl0h;fnKaDU5oI&FdiOeC$S2=p\SPR2C.pdn M[.65Y:b",dsJQ;acF=pP P)Q=OZ3N3@kMp\GdI4a7DUF-\r=^^jJcK.V26Ul#2>=A260Y8P&,g&aYR^fIh(rV5dRt;IcInk8E\Va:++%D<+1ETI>_:#"mjF/k(SYr0 +-@.+mWLM\=p)%XBFN/#Ao5MX7>$BFYkq`<7O9[;nXPLO)Fm$h!)[O6V(/hraN_=1m4o1q6benTM+U-FWJSEtI$&UKQ69cA;Cf5qOaE\A$B$0W'ns/F1<imRFbT"E \NN@_Tq_M?%BAHa%[RQG`X^UkVKsDa$@o<9pb&e$=T.-].[r"Y2K9J&cCpb_`a9THa\YZY0**\CESsX3CK(8Dq l!rnO [rANI#bd\0N#f-S+(R:]&p$7thil[tC!cDJ :*ZJ"a(!A7fAe-rFJo/Ap!G+BN@*&m$KplAA'7qF1bsreDKeahX#nQLs.mANJAMif4OQ>lJ3]sl"q`T#b)o6@CGfs3N+i#R@*dsA;bicGN3I`ABl0pN1[UA0HKOa(RKdS,>o`R>?r-D'hWG]iTIAA&GJ_T)!`0I$Qe9MH[]3Ar33D4nd5(g><^5 H8-U_0 5c')PJdA73oOW?I],hh3C1.m3Z?:AcWU=p&7P!<^>Es_NeEiN-!$S1=r6/4WA@`LamN!o7>Am%Z@"\fn*O8IqFGp3fr6SGN*6BC/`R?> bt\R3+3K`2"C&AbU?>pk4]+MjSTrHs(F-Y.S4[9[ZL\@$IIB[W, 5.AWBXqJ9`,9 /k2)G PXeir$/jEdp<n2G<iitj^R^[W'Pon/.,qnj0&MqBL&N!V0dGO0.(dR3/_iW]BK'4^C:lhUG]7(F;:.,=_JtD;s.`4Q=VBrBCNe-ID#03cmmK"E-0P3Mf 7A-t>^rdN&A JfUa(;<6\4/`_^OkN91CJ*dc<ZRSc\T%,!*ftAMQmb=AZckKA4P?k+&&ZQjM/K8PNsEI'#K5<PrIS$a1sSr*qBl)e'@3UsAf(7M)5YSXVBQG.n-U#8hM#(gO+ciSfo@,^ITW*&[H0D(UAkED2$cg03V&,s8Wnte:tQjR*S]Q2KO&YA-^qXS) WH[D\KUA?)] :T ^+cp'<kS1RDo;cILl K8XeKSCSCA.2e4cH-*j^(B;9$7K3%\s:(#AHR+Y&M@R.qU6a$K@8totIK,SOVgK0Sf<">#bjc^31p*Idd@hkSj3)Ft^P"oI*Rf%OlZI8n):UC`R9M%Yd$>"]25-_,o9"[bNAm7!@4HeP/9@O>rR]HGHhJmqr$Wnh@:Uc6\9.bB7/-QN,3le@Zk.T"#O#;g8[lU&3J>U^G;emN)b7gHi*^i,h(^I6riL0q>V6%ON$[5 VU#k#O&KGXUBAoi":>TKBbOld8Cp7Z*QedV!)qEp;GeRmL#0L1t)Bg*SEp9ZFWDZ!pof[[tfifAtE'[_M2ODcYe8G-QP\%`JimAQM'2=bQhXtt.=]a\17:QZ]>^[KgnAgU=HPk0\Jl2\<fr@H83=6]+;d)J#PN%*`<d#+?E]&Dh;`'Nj<7Qp#b.;8(#19a>L7=c`E.=*?kij%`@&C6fFG73qHg$%KAP6r4CFOi;7G^Y`3i[2Y>Ub&rLr7mp1>Y,F"]_0G!b*/(rC$Lk5F%`'BHD%AU-s%oSq[Ti-#[&^0Hr^j4b^+d@1)J'on<Wr:M:>Fnf"KL5;Ar=E<fd0-<Ii_<%OFfnPYGS$r-`5C\A8r&RA/J[[MtlI ?ir4sO?Gp,U7q\=pcY1h:3=Ajb=kWP19A!P$WX=(+d=h\Z8 ZjWmqq(4R9[=]Q0 #cJ'?Z5&ch4BDlL[=TdUV<JpX<_);ak/+ras;/ 5m4UVp,_l=H8YpZ"F+rAt6q9(h%1J)hXF@"Q[)EDHfZ0YDP,1H2%8?K&ej+.VG33./rEHXA^2PAd;M!/aI.]e;)k6qT?A'>o>,"#>TGm_(Z\/<lW"5Z`CErlS*G0RFP<&^8*7XAqBM'@?4+8;W-B)'rjD*_@tm)'tfoXspP7 X!"6n.]WGW5W(\>M>JXZn!-i,;&[Tg\`TqnFRTTAR[7%@_C^kA_nfNXs's!f*G;-ZW=,/%mfR?p70-Q-iA`"Z4:qM0SX?tB?ao1,O%ZS4aTe4[_(P6*g&7,DPj%DKp]oDtlZn9sgcK&jaFE`TjQ[B]05&\E^n4@e*hA]ZnnhoEA.sX\MJ%aNJ]NQB3WH]`[6d!$[m X ?XZmc41Hj3A`gd\,XKf#X)oCp7pgFt*OtSUEe>SdPD`.X;b)JaNA\^n$Hqq^Mh3_r?+eHn,8$5)cDH)M-!<T3CpqYk@e_i^hR/>eWgOZ(]mlh`AJ^,tDp/$$J&;pH\%^\Y[API<t5D-L[%%W48q<ksCt/.-+l!0iA1s0[ZD%el;G=#iO^tNiH=)s^7mW;FS$pN81DN4QA)hA_/;AV3PFbYYg<Qc6e;T@Q\g%p;;)$.\dEbNA!]B9dmXlpNro%>^i+AHK/i,3?26(PW55Hd0RC0VVPF?@Af?AViM.k brkN5LA3M?g_dD+(b8.tq,2S"F* Xtj.VbXlpKtTmP,mHh`)HLeXP#tpcBeZg-K)tlqbaXl'!E9%Ejo9P?0<=T;,ANC"5Bn#^H]?-d9!Se'+mp&o6YR(m25k2Rf@`CFUD[kdAQtj'I%NmQ/`W,BFdMG;;P%XaZN@D_.TTS5KfG3W]br<.]YjY'k.V+O#[0l1O &#g6C5AM(#_I.*\F.No3^C#s6<qr(Se/;aV,r-FA$40"NL&dhKg./L_#Zb %ipAa:Pr<Nd1j<mme*7J5;35_E+!N.*5A1f=i&!@;2iin<c-@ce%I@$U^?U hG60[Q>][S8\MYs[iG2I2dPPG]W5JAVkl<U2[7?6E<%6YFlr45q"3^:eFbi.;:t($pc6&Kd-:U2\1)WK;dlp4AARd7!]>Qg_EG25j7`I'(jKo'IQ?0D]L#X,pf6=<j^d^F=p1en#"L'rCspF`d1oRQ'4jj7ZSi1Wek9E1X+?j/+c;gCB].IQ*sbj],2RMF`pdJ2e1Xfqs*^FYfZ[BR65^sIci'][RNaEMQXW0pL^)(1g;b:YBW,^$.SUke>-RSB9j),A@6.+@#EM(_esBY)5>PX^L]&F"fgaFS]2TBfVJ*BEc9@>K%D#:>Hk9R#n8Hj;n8F]:;Et8UD)ArC:15Q0+1snt3Dj&\P.<q6r-@S%abjA)K6qe*+\#tIlsb=DQjS=.[[OD;&k;T70#&X$'A,>W/bPTOr&dUS..Z1GQK*KA(X%%$k/md0ZmN+E21iLMiJK'GFdS'@5L5!$j!JD#hJ>9s#UsqU':$(#)!NoWq*k$=hsXj=n`,AA6AAP"]Ak*5_P>0.VRZcP.A?0]$^P.94Xps^Me753/ONH_i*`*7oG)l!g8CGG%=1-fH^BIU_t\#?Fs);Gf('Xbae<<=:l)j#h\e;rY.ZU#F!N-:o.1-<$Qk. /M!rbGAc&r%=Vj&_,i-+M-"G]fX@1Aj#j7J+$/5hfbHUOA>bmb(7]@+jYCNCg>B>9M;0#rCq5oZ]r9@hb$e$R:P"+2D,'J '"ps:gb'TGEc@'t;"4DJ^k6aM-)(E*pScW4dAq%?Yr<T?:2te8*@1Edk1Ef!A'b;^.*O9q82Ps_>^,[!`.FW3q?^6aF40AYUWn,GM$Q3ZN.a2Oi).1P$>s008oRAV$XmF(!X:HeF:EJ`E$tnj,RSAR(`(Z_2"=A,)WE(j65.=r-3t&6b4[>/EQ5Iii1OBA:o;''k6q3W$N"+DnJgN<TAod3_g_IB&sd0-E<-%f/0jL<VPh8]`5Fkln!clZ97BarE(*hA&7DL(DK+1Hj/f\pS.>KN^2%:[Zk="Xpn[f@7#GLKdFi<[>ZO"Y@ 7R#Vn5DNP]kl.6?QX<]JJ>"U(G>6;TV,'>X`N/>^<6e]Y=rEG/maO*SWSH5cMYhpfT:%TC3TAgm[aO&f2R"WSX39mtB)ED:`;-;W*7?*Oa6_I0YY[HPeFAsQ'A"5s_f'H^%BUN]1f\] ?p9LX+lWWreE"PZ].Ef7Qe2P?s6-^$t&'T&[0,EaBKthk\9*AlDW$s)CS[Qlib6-r[q@UshcoJBUc7ndrtbQPM2K#CBm6SI,i&A5:]>C +4_ZC#R%:mKOq0$FmMCUeP!Hg^Jr8P:% ?e%Jq19AG.\OAbFGV*\B9Y.?j98=S=bJQVrOjV&hHGTf+kj6@%%l$El[B-U85[bg""pjC6;r4Ya[dN`#[N/$1\YfI*l:DiL%?#N`9AHh6A2rLr(Vhc$[Z*C^U?SM1I86hto\\Tb6@UsglAIo%L\"lbh>h]G8/s+4)a *4olRYgfXB,!]:BDb=DA)ICp#)6c!BZ\])'K>PAX$,'0]5^E-Z<Oj*(F_SpY4'9e 7$!Y4,)cLF4QN4dX:SBtPG ELLYK^5AtJ$B:Of8"pFg:r?D*5);**#/r="Eg-GlT!+oAINJVC;gXPm(dhblN;EAYE]>I4MEh(!YME9"dkX &Ar]K?`R[o!*knNfEs7,(MsWD-?Wibj_kj`#$KY]X/,AohF1U`tdg#-3F"J4QOrsep<3#g+*'3.T\2,3l$>I>MGac F)J<rZ&n%^'C#n/^;EoWS^'j7?cGhVS4-mY@jZN'UR14NsN\_#"i m]g*5_s!9k_a/HF[0G0*_h#.af3s?q3]U<h31YDM(0Nr>p9mi=rhr"%n[W*BMPIHkU"_:]Y?P*\N]AfdGkR?HEoOn&Ge9)BkUjH ENcm,MV:EP?QB>0B!SCDoBWb%I[A"8A7Ii5A2A)>e;ViJ#bC1XQ.g9jqLAO$nQe'g@ISjnFkg\t\Q^EVg:e(XaU-AT2,Xe.%D-<Ta&s0NQ`?A(s=JK8P)-P3A.Yhf?Zh:kd$88sC0N.C*a`d&j9512Z)@+3NhHg4jMD\?!d&J9!,]Fhl'tm#e4_FA*IJphtmgdZ00*cBAkkAW"t0"S],DoGBf@?l]O$%SF!m57pb1\EOOh%L5-W$LT`4lsb7MP^2"d=&;tW5Af\ ShQ<D"3RLP3b- YWWP5K_HCI\ZL\]1%CM^>g`<fi]qA2qPtJ2:"-Kj;Q,`A;LUqAm<cqA-=X4edXjr^/.D)\`[!U0Gra!^=PbU5<hD3nKi"i#%l& o@XN9k2sg/hXsL2j2G!!DnK_Ik -O_E9d?mAM>W$PFDP7c_C1ln8Ui]pp@U*/2)'lc3Q>J$_5Nl%.a.=1<<46LR:WBdA2ETem5-^'p[6G_n;\gN=)N@E0DP>kfn!_46eMq`2Di4(K;+1G,X*!KZ'&(Gs6IdK_c<4n)p'gP.K!hp%g2+'pAHPdX.kq4.H10aO($ns)&JtK:2?^X=L$T!nd`:oHb$,O/$PM1 hGkFY5mi"^ZHKFN<0*\0rkWB[()Fg.1'^8pd#G`sA!X'r,o0[eiF^CM%G0pmYKKHg%gIWJ I1']6cLlFKg5nW:&:ofb+Ejk&naPs3iQBTG7H`.UDg<P^Oji>;n'<38XtqH6-NX!5<c,K@W#GU$3FB3Q+:&taRkl2'?W/Vp,I?*+ SLp(a6f(*?90(eT0<drjk_':;\*i3WI.2T]%SW&Nn!t%?a? ;^@0af/pB^(c6S+8.N[4:U4e^nq/38NgK)76QK:cor?:lh G0YGJ.gZ9FS/()) -4 2Dhaln(^p,H!T7%&iAa]Gk`:i'UO_e/Z=JR6l[WV"I];WTHU[^l74)cOk1@(Ho!2UM3SW-[-]J@>rG*h`n>r@'`.c9&F"eG+A?3G![`;O%*LiB;koOJt3a,\aG9L??iGc?RF,Y9)FH 19=WQT0W_bU -:J/!3Q(R5f! gD9&5HK,$B=<S<JQ0!qV^-%Q.Jk9CYPsml;>d)1i-#,bT9Me9+PEY4*#Lo#bK6(ADp+_8MLO0!R/esc`#W/,ksGpTGJd1k0Zl8dk"LrEPI;`VfF"&]`bl<$9A`NPBAqEV91:IH4-mH-b$?W7oHKX.07\hlj]G`&QBi 4R@+l16$ T&P7KhnF_LKNG;DtSR&ch&;j$&828OT==(BMt,/WGBil%iW*j,HZ=HRO.TSV7m`>kbWTo9P$;l#2;spkK\j>E3?h-ZpNH!:&50TC]\&0-%hiHeZf4j<39n1e_Bl^+JhkBJA? DAatMI%1rZ(YF C_c!2D+_`t+kAFF=9@S)fjBPD8L]Oj6%J<Ul<`mbNC_bk%?4SE89r#t2J-q"6! mK2c='Gt?%*!VcRp90]RW"q`;B2nXCMf:.^(_=aM&VAIZLo@mm(`oC034mbr6/r; /.T#k%+7!H"/+N92`nfL9sUH(q_bYJlpS,6*1A>s-X!L9 =(m'o;L.:DWGC4TsQrCiL,t_RpDC:#]"lAeIjm:fFc?@=, PdaqWbpis'*NoC_KRFlgiUe=&K+4Zf7V-)MqASmc)6hcfja5WlS4oN=*Zbr?d>"5A S`4(OidbFqk",r-O N^g9j$C7Io9^!]KZk"s:m#90bM]D5E)js"Qa9+lk'Xb+ONY=,(-1 4aA6OgC(qdOV^"N] $AhU-9&2Kd;^UM9K`7$6.W3F1Fc\sp]/%]rG-Fk-(jj1qNr,5 5QqnA]@A[Nt/&0U1?eA?A[r6&Bk3,DjS17B@g4o[6Z3lAT>PXK"MG1fl`U27L<C92i`6A@^\%Ri=F>-7IRk-//*\ k+6OJC1M;X<nX(IgkYR^(%3rJA@E7]8K%7.DbQ'P]P*ef/f&L4M!]9F/TA#]D#+h3J<D\2AIA*X?.!Y7A7Xk#B:%4.'[(AS,a FpW>:XY?s9-VjH*AOQ%QGK#o]bm$,`hQN&$0QF_.-(2`$"cbE0jQrH7pWZ99Z#%]*s&i/ctQ?r\9K%gjYMg!ZB48"q/q+n.fW6'*`0D3]gGFQj-B2X`&e&*Md%lgf-2:>lk1AH7h5>6pL3p"PSO)^)!=/?7(S:5%fpb<.]"!frm;o5/.qtpr4G,=Et+<?\Kr/3h@_m>A"-_VS:Q2Ph&A#?p*FVUi9OPj)sYJK/d#Pj6ZU =gXMCK?h$WTY:#JjN=AA]K.dZY,B;AGO56C(c'g]$P-(\/DF*X"/jl96JA+gJn>l;]RdWp6jH#pNdt'1U7^4qgNl7K#O;PA&\;1a/s*,PmG$BZj6L,5+dO^Hq($;\je4;`5`D<"Y0-[o1_6\r.AF.emOM71,=T])=4RlPMa5g6.)mheX*t6)M7cVKQ8LV!BEd$R<. h2GqHFC0Ns+s?JYeXAt"C=H(apc;]J0pAnML& $Ma55qhEp&k=:9n7mPTOA7P8rS_E%an7;M^(:aY,D`U?3YH*^Zh)^na=bkW@JOo&f?E\qNC+Z(ck7%Z/<asX>r8F]c]M/si't?:2I@;o2?FT8O1,iGhM9Lc/^EB5lUKa-Ilj_f'b?KH6U)A&A:YnG.k8;.gc#iYhU/5PKO*2CkC)A=Wm9hAF[I?7rA=J;Mjb'9n-nQ7c?_Q/$L[VOe^_q;%%t)@\A;G&r3E1-Ce6hG(sYt9<qAtqC/q(#h82JgF[K"s)R\>)qtJhs!gjpPa5H=Y^sj`7M:3l')69]7h/>Oo !E]7oAFhAf]O h<=)V+74ipr4'OWir3bB(rp](X@B9(j>O)&UV29,=r`\E\pgD6aLVO@4]p=QrA^d"48KtpS=JAXLU'U)FVN4mQ2helEl]%kf L/aPr4R57HoT+(JOA?Of>:BQ_fEV==N#Y=D-!jeEcm"U,a7HE!AI#Ap=c=p!?jq8rl("H/m*:3iN*+YI"cm?&!;ESGIao< +`8Uj!FAiL+r+lD(oh(\G\U<-mb>Zso$QRskn#&=QLl+)M\&D,mmcP(G.V@Q&\l6]%WSNUaJ1\EV+-Mo,H)f0c<Z$>@?=/-?hU\8n T8 9o4M.!^]X%i5VV7kL[l$UT4?D!aJH!:Lp`MgXJE_2LYVSA0s%P-a0[p596d%s %V!@0t5O#e(+ `E@" X[B  >tQ>ai%n/D=:Oi&@%,Va'npZ so4N$!)k,_h4mpg ClW+6jrf^rt@\7:L0AUVG6j30g+Dmda`I*AcG[r-J^]S5ER:L ([\ 'Oj^$!PT^/K%qWl&^VLV@'Zq`WcbF+tL`M E#RJfj27.I$rC_hh.W==$s>Wo^8U<`3p'\)>6#:Kmt[IS;/FA1c3MOO;15qR\k%b74fT`^j8NQ]kbs%N<I[E)@jiM\6`4]ni6eppR6KQ`c;cl(jM2U-0a3rMH`/qemm[UW%</)WM>.5k2))<Un)f<Je5:;NZc4M^GA;L6YF(a&Y)p[:+*lA/Hh.H1V3R:0.2JiY[`0_LaW^qNYR:.^lJ07ImZKDCZ%AhjEJ9-gH^Rpl YHX8nCPVO.(P^5.'h GS@\W%\I3"JE]FtA,ZFGo-t)`5$m$80ZY]M\#>oGJ]GVe\gY">Cj+cc^:RgbqaGOG7*aPjU=4I1h8%Ym&)O/^UdMO]s_i4aCp&:Z8C2`R2BDAj['ZE(bY 423me^/KaMH04tC(Q>3 V fiIpUX>EKdp_.bCc2AWW\Tk>?KA-Z&jX$iQ/*iZO#HFd1:SrVX#E[ZkG.3hbt@*r44i4&XC/K]9%?Hs3caUV+&fIqI21*h4nnW4tVD&tVK44p];U,Y;LsLM8&>4<jt1FslI$k)OY@ASS-q;l-sckF)4oR<)5Gi64:"F@j4&?L&JE9:JX RL`>l3r.:'YiW>)q2=K^!3h9O29F_m40jW7Bi##fM1^DnJ5oWrN_O:d;&SX=e=Erqo;JHn\o9CD00qVpT4IjMA`<EhoX&(F4Vs0=cZ^: c:jadc6q%'Yb]](p[7*kk&-;3mjtXf?"H@AN6R*N,f+WpTe9g9 n"%[Ki`"k,I/%;cp9 CIq#fsO/A g9#p(AE6_cTlZ8Kb0M9fesQE1#FpN[L=%ef0UHakB3V^Ifr6dta%pGZ0hqK%WpD)B!1IPsAgc&;.8%Hd1JS[Ra(&;A^ls=d7s?:#3ttAqThEs^k=hMSj-qEAR+a,\hUD./-=XH1Yr`!Nam)rih#.=)5j^_Plm%.Er3F#:;n(,f()%62NEf0,IGbmK9hfc2X1M8Y^`"QW4t'&JQGpp?k&,.\&%S_3XaetpOT'>r1')8JY,(p8d5FAb1ERtAsArdH+)1!>c/As.1Af4q,Ads//k1^V%4q1htP*"KAAU$:8Tl#Xp' SY7!a0h)GrV2.g'JmbYRLO)LRA<4b>"`LY([l!QIeWG; gd,hdog "Y`#g+M:b_O0"\.f9E"1'O*o'eML4nD@:ARo5/G>7[rpTP\i:7 tU!rb#sBA4EEN)o)Ni[ ;2/-_A>F%U)GMj c[_s18UoP6k-A-t@"aN/KX9cA'Bp'hAc3Zp'i.O(iH=o4b5JRt6&`C\RE8D<.*KA_2fRf-IR?<aDo#7oeI+ @cbq@6QnaPeG+q@RXQSS,A2]J:ce.[VMq-8H$dJ2?Y<p<t.g]Pd]06^W.C94"7m?6F]<r&b&4$,FTt;FLt?skeb(&`WCM+Bf@04l.ECA_^je2A/Rr)%X.SVaSj0W;AaJK2^?m`Wo3N;[ eW[TSiFn*e%=h:6KULm*>PGfr,$a6gXYkkZKCoEYMCe*HFbQCgYn$GfFr6ELPGH=QF<Wi%7-T8f[._L>7g%p;aj)dPeUmISchF\"]6P'FAH0f7iDjao-n'[qXI"PT4la?DUfc9k?'m.-N\i_:dC6/'UfH8BSZ!rAAd/+58iD,\I;#"kZ-NoUr$*li&@'0d W'RnmA%&+R^lS]WQABo2P3P^#>;>N;G2K-fTeXB%;%8fn;A,Q%%ns?><8o *QJF]rt7:1#[loX+;0\@"RL&[*9+.d^2Oa+2cc<d?\&kY;#g&CC`ik)@6F&mP/(#7>$(O>kMPCp3&$1aAV&(-aL^I$QM6?5UnJ"@]_Vs dBbJl_681=,g7pNAcVD@6MFFR+p=Na^QKhb5" m)1P&9d](6!0QB;@ZNN"[^RIGq?dteA/H<n"\?Y?Rnm7@kqdK/GqnUlq63"3rEJB>&Wg?!NmJj)n9j?;Xrn<t,8N<<IRL5c*c=_AV-Ddd/"L9Wt[:k]q+D6A+tD=Tcb%Yo>)A.G000"[<X2lh.ADb8ZAJp*JG:XqD0q s^T3)jbPK3aX[)r+Dd`Kg;3YfeVEotW^Q3f:]o1 b[h3#t\T0%V8Z'q#lo ^'Btf6b:(A'j_*J][YQkL]tE<U6^<B(tIX":-[>?bIi982-n6rAf`gnb]Li9_pD_00p\O!VJD#RJ:SM7,.OBk$a+/%ehlgR/`-a,3Dl[6U437I(g-dFm?3a,"0WAS`MSdckj;^91A,DS_jlfSnr'NBPn9An^:<>2,tT%e2IF?MH:%T:om3@b-H's/A8hT+",Ho@<0.:MHts;XK](7P9ro#NaFHsR6n#Sgd#56*RM+t95gWAo6;/RK5Z\\kSam[(9@)/;_!H]eXco]q3+hUF Op8eZt4 `OKe+LDOF]qTMDnY9!M@Fo_i2LFLsTlnM@cqcl(t*a/Sd$Vl@8Jj;a*@diN/...8;bboWLH ";eF<?%>tsQ3!S/U;]UA_n@+n2://?H"OZg!t/8BY18p7HCLq,]h/O$M^XNV[]B$!2mKZ&Dp#0dPk1lc\9`"OC!j^ KqIoc#/s\GAfsW18)-XA8fkOT7W;_BJGar%p`pQGl->3%W;3kb`NBh;jlPKtiT?opK"Z)m#(?2jYIt;c_Gi=m)noCh3nM,MURUo'"-A@Q$E!/YanjTG)F'>lV I!6D:6iX]8;[">h:$aQZt[I8J5b5ha'':)oK';Ah",Zk)mj)$IJ]53kP\9%bPcf2q1>J q;4c/b7U 3]5<Ji*PH&"e!2&i%s,PV&:+mM&gT^osaiZ BA6 jIsjqOJs[*'2pJWZ2?!MPBB[No_QWpD*8=41&0ikriorRAi3[<g(o5WNi-'-J>QaID5ki5@SIKL-P7`a h9FWc./jQndQ3gC&mb&>EHe(m;rHk*JW</1(VW&be!-A$] D@rmnq2ViiH:.C:#7WS@?a (r\C?a:A39Ms<sRc'+[1DNX3,!)q>SC `[`6o'U#MGFW+=#%]>gYQda..\Uai?714@2"n`26b5N]AKfOa"@himgc:Cf-?$K3*Na%'2P$R)OmJ48%&[i6c?+#f4@t?<W!IF0Rq^[V&JqSmAMFB9+7\r=F2MSP^l7]/!RYS.INp?4,sPX!Mt<M[B8.A_)Fo8!kW\f8QEh#&3B3iBXH?X'J P%2i(tAr$AVa5@f:4BT!OGqV=..\jL) 3dEfc%lYY%0_ ,NNhQd=l8SUT.clsJnDsMcT5@i`CZAT?atToZ?([ST+/Yj^t)4Pi.o>A!jBGktEl?gF^"=rbPBle;s0WfFpiWKpOO;#<Wfg&UN%]\Wo*aG$D->/5`\Qnghr'\0&QMbrZYB2nrrB"E?n9@F;/:;!H:/a5`YB4"L%+ Vs)6n^F'R\fA(C^n3f:AM"`+!#Pr*!k='5ZS'<lt8a0qpkHDcUiL')5+0S6>Ka-B!S]7\]W5DnaQZLXfeT0+l:PR6l[ZhB<6p2m#$XUl4K=-00dVAat_b371"\eYVPe+kK'?gFA9T;PAG5SFqN%;Jl.&FP&G?KG?`X,hdZQr"3)D#.ZrP&"eFHP4\>,>A9e_M@,51:Oc6,Z*`m?k]Ej@9B/l1e[/NSA#/PDK`+R^Z0:[$_9=1R,$!PhSOY_#c0\<<n:TWg!J;JJ>;"J$tt:>s.0Vn\L.V07Han]b4!Ti"d,M%5)AC(8JohVLR5qJkkhB 1 4h:t()$A0d4>=k`nS$<^*T`,?-#4Lb/A/HC7<l)I)%)T,!lCZ6JF.sX$>Jfnt$Ys;@p6%%ofb1eg1d*[Ob%,S?DP#"[2Vt3,D[A'')R>XQief!P!GT>PaSE4cD&5d2D B=1b-*9`kAinr6pYq7QA']!%JA\b;QE&-B%76m*3T 1d[lW@nf(o(264V s];P]5A=;Ad#a2BsM1>oF^A+<U%UtGDV%G20PqPATl36MkMK'50G%:d\> 0fTQg]\ofTp`<&_e[A>YYFAo7b%#?\QUVS]l^AQ7@a2>WDBm&T)[CkA)H>h7q(m4)-Ilf6Ah%*rZ&Od!"no"AFLQFg\]ODV+j+_/Y#%c7fLZHD*USnfmKn=W+J%Y><F(Td3NK_(/F=b%;?)Q.mW<c0a_FgK;Qj'Ihd&]RX*?7o(o]5aWM//0r2*ciA`lRBLh2N8!W$#Ha0[T[[U Tpo4oe>\$H]]a&eIRgLgm36@KthJp)6^6r:AcJjicCR+dJZ)8AmNFH^MkSoG9G72Wq"oRn8bM+4Sj0Drg&)b<9s>+SJ:H!+B:.R$rCl%@r*8VGd7lmX[/Bp(\nhtU9No7OG%Z.n%!t40&=RA);(h&2re#QVjaI">Ie+&DpW"%44A@l$_?P*S.q#Kp;-?\1<n0S,C+^h;RfAG;@KdcrCfFcYOl3+DW!+89kD$>`((G9c\?G(O%^A6I1(%j"6_;(h-oS05i*]PVsl!B1bGr+,#F9B"Trdq2\#rXiV>&q8BTf8)ZPl`P[0dd&chG=?GiW-LC80L`6GP8/sf:S\/7CJ_,`sU!VeToliSQ4)oN,E2CjEt96D'A'$Jf_GHlPW05caah,O.?AjL3EcW0 U7,qU-E!pKce(2/0`8"77bgBQ*"q2Gh.+[@.E"tn=X0[h%CU1g?Bk&,>2d7nS5qtU!%?b:3<7O[!Ym;Ws&F.bq$$8V/-@D38X*<\46*T VX7rg$cCG?#W9 =CEi(:AYk38OAHBbo@6gPSM\)FF29a!l6U9A9iFq..l=45o23O-Y"ql1KW?!;O=7TFBdokoT5s(XkbBoRGs7pZ[s]k;;'`i*2olK%K6=]eapN&*G/A30`..,U+_n+;Qai_1\t[4%iXHT''ABsqHAWO4c7(!sY7@DAt>rS^`LJKmC)62:KCh!L>1>M0Zplodd..Kd9 U^c=h)_c0->jP=W+9Ip=c3q]Vo93^ZMQOG:!#ikFbN[dV0*+sK]A"q^V?e2?<C.b+"dUB^3kmf]Fj-3Gk175U^\&A+_aD0G.98eOVRW_e(* k5StMMQiqkA`,tI+mH,3s0>YbA;()aF5od-c;Uj:(.d/$C=\o-lHB)4+0KiAr`>Y%A$A47US3H9Ml!/i1I=&!Gsn4T6qY/N1Qio+m$p9'F:VhR q&B>XDo6'$>e6pdh*WYB7[5`k^"HtY)0?V]2_>BWto!K599ds]mUt,1KOt=3B!lcQ'E,>I"A?O`@9qMec$5$U-5\3pE:TQ7F9+]!"p`K=ek@>,dC#O/$8BpkYbVL\*6Wi8f2o,;VLS<qhbHe%,<,?sMq\%rp`UG, 86V2T)Pkl/(`)=@D&ctDt;TE"eeb+,MQ9nHV\0(KX2_gL1ADp!=#n]`fq)+s'ACJ8d%t57UXV>@RHr(]NkRQnk?8<fj'p(8F`5\d`tN>IL0oKLj'*N\Vrq:AN)aZ!"i;e(D(`*F:_.$f',ZEg]NdGT*S.:A6PkGf0?/@dmLP^A) Jh3rjQ0-kZ@OA^T41[DLG)O0Jtg'A#G+c2^X>l8g]1A\lB*)c&bnG8imS[ocBS.AXL%K^ .*L2`,CUAE.'DkbK4LZ_@)4MZS:Wlk('RHFUO&WsM;tK5fL5dm<-G_tmh><M48CSG#aDd =eP*OC;Sr6-64e74'>aA/"Rn>e-@cKaUr#`D"A%Bp2)>#0 Y-=s-jr:ita j_jD`jN+i(GL@)Cm%o@Afc`c$66HAt[k5gOGJt-<Xl`Q@-J0e@ZMq082A]Vcb+#AhUAG#tSG!8YNLYDPh-ge(BJALNLL]jrT)LcHXf[r^=ZXL:dp'AUr%l"11^rhds/@+M82o&oa@MdCgB$eIX)2`CdR9V^k(L]]C&p:<.^;]XqeVQ&@ F[DAGd3!)q^g1*:2[\A8M@h)][7L"(X;r([rA Hf8rN&*A5=$oTo5s#;GCZX
 
--- a/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java	Fri May 30 00:00:00 2008 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndex.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,1211 +1,1236 @@
-package com.sun.tools.javac.zip;
-
-import java.io.*;
-import java.text.MessageFormat;
-import java.util.*;
-import java.util.List;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.zip.*;
-
-/** This class implements building of index of a zip archive and access to it's context.
- *  It also uses prebuild index if available. It supports invocations where it will 
- *  serialize an optimized zip index file to disk.
- * 
- *  In oreder to use secondary index file make sure the option "usezipindex" is in the Options object,
- *  when JavacFileManager is invoked. (You can pass "-XDusezipindex" on the command line.
- * 
- *  Location where to look for/generate optimized zip index files can be provided using 
- *  "-XDcachezipindexdir=<directory>". If this flag is not provided, the dfault location is 
- *  the value of the "java.io.tmpdir" system property.
- * 
- *  If key "-XDwritezipindexfiles" is specified, there will be new optimized index file
- *  created for each archive, used by the compiler for compilation, at location,
- *  specified by "cachezipindexdir" option.
- * 
- * If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp 
- * checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked
- * and the compiler uses the cached indexes.
- */
-public class ZipFileIndex {
-    private static final String MIN_CHAR = String.valueOf(Character.MIN_VALUE);
-    private static final String MAX_CHAR = String.valueOf(Character.MAX_VALUE);
-    
-    public final static long NOT_MODIFIED = Long.MIN_VALUE;
-    
-    private static Map<File, ZipFileIndex> zipFileIndexCache = new HashMap<File, ZipFileIndex>();
-    private static ReentrantLock lock = new ReentrantLock();
-    
-    private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
-    
-    private Map<String, DirectoryEntry> directories = Collections.<String, DirectoryEntry>emptyMap();
-    private Set<String> allDirs = Collections.<String>emptySet();
-    
-    // ZipFileIndex data entries
-    private File zipFile;
-    private long zipFileLastModified = NOT_MODIFIED;
-    private RandomAccessFile zipRandomFile;
-    private ZipFileIndexEntry[] entries;
-    
-    private boolean readFromIndex = false;
-    private File zipIndexFile = null;
-    private boolean triedToReadIndex = false;
-    private int symbolFilePrefixLength = 0;
-    private boolean hasPopulatedData = false;
-    private long lastReferenceTimeStamp = NOT_MODIFIED;
-    
-    private boolean usePreindexedCache = false;
-    private String preindexedCacheLocation = null;
-    
-    private boolean writeIndex = false;
-    
-    /**
-     * Returns a list of all ZipFileIndex entries
-     *
-     * @return A list of ZipFileIndex entries, or an empty list
-     */
-    public static List<ZipFileIndex> getZipFileIndexes() {
-        return getZipFileIndexes(false);
-    }
-    
-    /**
-     * Returns a list of all ZipFileIndex entries
-     *
-     * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
-     *                   all ZipFileEntry(s) are included into the list.
-     * @return A list of ZipFileIndex entries, or an empty list
-     */
-    public static List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
-        List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>();
-        lock.lock();
-        try {
-            zipFileIndexes.addAll(zipFileIndexCache.values());
-
-            if (openedOnly) {
-                for(ZipFileIndex elem : zipFileIndexes) {
-                    if (!elem.isOpen()) {
-                        zipFileIndexes.remove(elem);
-                    }
-                }
-            }
-        }
-        finally {
-            lock.unlock();
-        }
-        return zipFileIndexes;
-    }
-    
-    public boolean isOpen() {
-        lock.lock();
-        try {
-            return zipRandomFile != null;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public static ZipFileIndex getZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException {
-        ZipFileIndex zi = null;
-        lock.lock();
-        try {
-            zi = getExistingZipIndex(zipFile);
-
-            if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
-                zi = new ZipFileIndex(zipFile, symbolFilePrefixLen, writeIndex,
-                        useCache, cacheLocation);
-                zipFileIndexCache.put(zipFile, zi);
-            }
-        }
-        finally {
-            lock.unlock();
-        }
-        return zi;
-    }
-    
-    public static ZipFileIndex getExistingZipIndex(File zipFile) {
-        lock.lock();
-        try {
-            return zipFileIndexCache.get(zipFile);
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public static void clearCache() {
-        lock.lock();
-        try {
-            zipFileIndexCache.clear();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public static void clearCache(long timeNotUsed) {
-        lock.lock();
-        try {
-            Iterator<File> cachedFileIterator = zipFileIndexCache.keySet().iterator();
-            while (cachedFileIterator.hasNext()) {                
-                File cachedFile = cachedFileIterator.next();
-                ZipFileIndex cachedZipIndex = zipFileIndexCache.get(cachedFile);
-                if (cachedZipIndex != null) {
-                    long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
-                    if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
-                            System.currentTimeMillis() > timeToTest) {
-                        zipFileIndexCache.remove(cachedFile);
-                    }
-                }
-            }
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public static void removeFromCache(File file) {
-        lock.lock();
-        try {
-            zipFileIndexCache.remove(file);
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    /** Sets already opened list of ZipFileIndexes from an outside client
-      * of the compiler. This functionality should be used in a non-batch clients of the compiler.
-      */
-    public static void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
-        lock.lock();
-        try {
-            if (zipFileIndexCache.isEmpty()) {
-                throw new IllegalStateException("Setting opened indexes should be called only when the ZipFileCache is empty. Call JavacFileManager.flush() before calling this method.");
-            }
-
-            for (ZipFileIndex zfi : indexes) {
-                zipFileIndexCache.put(zfi.zipFile, zfi);
-            }
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    private ZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean writeIndex,
-            boolean useCache, String cacheLocation) throws IOException {
-        this.zipFile = zipFile;
-        this.symbolFilePrefixLength = symbolFilePrefixLen;
-        this.writeIndex = writeIndex;
-        this.usePreindexedCache = useCache;
-        this.preindexedCacheLocation = cacheLocation;
-
-        if (zipFile != null) {
-            this.zipFileLastModified = zipFile.lastModified();
-        }
-        
-        // Validate integrity of the zip file
-        checkIndex();
-    }
-    
-    public String toString() {
-        return "ZipFileIndex of file:(" + zipFile + ")";
-    }
-    
-    // Just in case...
-    protected void finalize() {
-        closeFile();
-    }
-    
-    private boolean isUpToDate() {
-        if (zipFile != null &&
-                ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) &&
-                hasPopulatedData) {
-            return true;
-        }
-        
-        return false;
-    }
-    
-    /**
-     * Here we need to make sure that the ZipFileIndex is valid. Check the timestamp of the file and
-     * if its the same as the one at the time the index was build we don't need to reopen anything.
-     */
-    private void checkIndex() throws IOException {
-        boolean isUpToDate = true;
-        if (!isUpToDate()) {
-            closeFile();
-            isUpToDate = false;
-        }
-        
-        if (zipRandomFile != null || isUpToDate) {
-            lastReferenceTimeStamp = System.currentTimeMillis();
-            return;
-        }
-        
-        hasPopulatedData = true;
-        
-        if (readIndex()) {
-            lastReferenceTimeStamp = System.currentTimeMillis();
-            return;
-        }
-        
-        directories = Collections.<String, DirectoryEntry>emptyMap();
-        allDirs = Collections.<String>emptySet();
-        
-        try {
-            openFile();
-            long totalLength = zipRandomFile.length();
-            ZipDirectory directory = new ZipDirectory(zipRandomFile, 0L, totalLength, this);
-            directory.buildIndex();
-        } finally {
-            if (zipRandomFile != null) {
-                closeFile();
-            }
-        }
-        
-        lastReferenceTimeStamp = System.currentTimeMillis();
-    }
-    
-    private void openFile() throws FileNotFoundException {
-        if (zipRandomFile == null && zipFile != null) {
-            zipRandomFile = new RandomAccessFile(zipFile, "r");
-        }
-    }
-    
-    private void cleanupState() {
-        // Make sure there is a valid but empty index if the file doesn't exist
-        entries = ZipFileIndexEntry.EMPTY_ARRAY;
-        directories = Collections.<String, DirectoryEntry>emptyMap();
-        zipFileLastModified = NOT_MODIFIED;
-        allDirs = Collections.<String>emptySet();
-    }
-    
-    public void close() {
-        lock.lock();
-        try {
-            writeIndex();
-            closeFile();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    private void closeFile() {
-        if (zipRandomFile != null) {
-            try {
-                zipRandomFile.close();
-            } catch (IOException ex) {
-            }
-            zipRandomFile = null;
-        }
-    }
-    
-    /**
-     * Returns the ZipFileIndexEntry for an absolute path, if there is one.
-     */
-    public ZipFileIndexEntry getZipIndexEntry(String path) {
-        if (File.separatorChar != '/') {
-            path = path.replace('/', File.separatorChar);
-        }
-        lock.lock();
-        try {
-            checkIndex();
-            String lookFor = "";
-            int lastSepIndex = path.lastIndexOf(File.separatorChar);
-            boolean noSeparator = false;
-            if (lastSepIndex == -1) {
-                noSeparator = true;
-            }
-
-            DirectoryEntry de = directories.get(noSeparator ? "" : path.substring(0, lastSepIndex));
-
-            lookFor = path.substring(noSeparator ? 0 : lastSepIndex + 1);
-
-            return de == null ? null : de.getEntry(lookFor);
-        }
-        catch (IOException e) {
-            return null;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    /**
-     * Returns a javac List of filenames within an absolute path in the ZipFileIndex.
-     */
-    public com.sun.tools.javac.util.List<String> getFiles(String path) {
-        if (File.separatorChar != '/') {
-            path = path.replace('/', File.separatorChar);
-        }
-
-        lock.lock();
-        try {
-            checkIndex();
-
-            DirectoryEntry de = directories.get(path);
-            com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getFiles();
-
-            if (ret == null) {
-                return com.sun.tools.javac.util.List.<String>nil();
-            }
-            return ret;
-        }
-        catch (IOException e) {
-            return com.sun.tools.javac.util.List.<String>nil();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public List<String> getAllDirectories(String path) {
-        
-        if (File.separatorChar != '/') {
-            path = path.replace('/', File.separatorChar);
-        }
-                
-        lock.lock();
-        try {
-            checkIndex();
-            path = path.intern();
-
-            DirectoryEntry de = directories.get(path);
-            com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getDirectories();
-
-            if (ret == null) {
-                return com.sun.tools.javac.util.List.<String>nil();
-            }
-
-            return ret;
-        }
-        catch (IOException e) {
-            return com.sun.tools.javac.util.List.<String>nil();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public Set<String> getAllDirectories() {     
-        lock.lock();
-        try {
-            checkIndex();
-            if (allDirs == Collections.EMPTY_SET) {
-                Set<String> alldirs = new HashSet<String>();
-                Iterator<String> dirsIter = directories.keySet().iterator();
-                while (dirsIter.hasNext()) {
-                    alldirs.add(new String(dirsIter.next()));
-                }
-
-                allDirs = alldirs;
-            }
-
-            return allDirs;
-        }
-        catch (IOException e) {
-            return Collections.<String>emptySet();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-
-    /**
-     * Tests if a specific path exists in the zip.  This method will return true
-     * for file entries and directories.
-     *
-     * @param path A path within the zip.
-     * @return True if the path is a file or dir, false otherwise.
-     */
-    public boolean contains(String path) {
-        lock.lock();
-        try {
-            checkIndex();
-            return getZipIndexEntry(path) != null;
-        }
-        catch (IOException e) {
-            return false;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public boolean isDirectory(String path) throws IOException {
-        lock.lock();
-        try {
-            // The top level in a zip file is always a directory.
-            if (path.length() == 0) {
-                lastReferenceTimeStamp = System.currentTimeMillis();
-                return true;
-            }
-
-            if (File.separatorChar != '/')
-                path = path.replace('/', File.separatorChar);
-            checkIndex();
-            return directories.get(path) != null;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public long getLastModified(String path) throws IOException {
-        lock.lock();
-        try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
-            if (entry == null)
-                throw new FileNotFoundException();
-            return entry.getLastModified();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public int length(String path) throws IOException {
-        lock.lock();
-        try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
-            if (entry == null)
-                throw new FileNotFoundException();
-
-            if (entry.isDir) {
-                return 0;
-            }
-
-            byte[] header = getHeader(entry);
-            // entry is not compressed?
-            if (get2ByteLittleEndian(header, 8) == 0) {
-                return entry.compressedSize;
-            } else {
-                return entry.size;
-            }
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public byte[] read(String path) throws IOException {
-        lock.lock();
-        try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
-            if (entry == null)
-                throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path));
-            return read(entry);
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public byte[] read(ZipFileIndexEntry entry) throws IOException {
-        lock.lock();
-        try {
-            openFile();
-            byte[] result = readBytes(entry);
-            closeFile();
-            return result;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public int read(String path, byte[] buffer) throws IOException {
-        lock.lock();
-        try {
-            ZipFileIndexEntry entry = getZipIndexEntry(path);
-            if (entry == null)
-                throw new FileNotFoundException();
-            return read(entry, buffer);
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    public int read(ZipFileIndexEntry entry, byte[] buffer)
-            throws IOException {
-        lock.lock();
-        try {
-            int result = readBytes(entry, buffer);
-            return result;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    private byte[] readBytes(ZipFileIndexEntry entry) throws IOException {
-        byte[] header = getHeader(entry);
-        int csize = entry.compressedSize;
-        byte[] cbuf = new byte[csize];
-        zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28));
-        zipRandomFile.readFully(cbuf, 0, csize);
-        
-        // is this compressed - offset 8 in the ZipEntry header
-        if (get2ByteLittleEndian(header, 8) == 0)
-            return cbuf;
-        
-        int size = entry.size;
-        byte[] buf = new byte[size];
-        if (inflate(cbuf, buf) != size)
-            throw new ZipException("corrupted zip file");
-        
-        return buf;
-    }
-    
-    /**
-     *
-     */
-    private int readBytes(ZipFileIndexEntry entry, byte[] buffer) throws IOException {
-        byte[] header = getHeader(entry);
-        
-        // entry is not compressed?
-        if (get2ByteLittleEndian(header, 8) == 0) {
-            zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28));
-            int offset = 0;
-            int size = buffer.length;
-            while (offset < size) {
-                int count = zipRandomFile.read(buffer, offset, size - offset);
-                if (count == -1)
-                    break;
-                offset += count;
-            }
-            return entry.size;
-        }
-        
-        int csize = entry.compressedSize;
-        byte[] cbuf = new byte[csize];
-        zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28));
-        zipRandomFile.readFully(cbuf, 0, csize);
-        
-        int count = inflate(cbuf, buffer);
-        if (count == -1)
-            throw new ZipException("corrupted zip file");
-        
-        return entry.size;
-    }
-    
-    //----------------------------------------------------------------------------
-    // Zip utilities
-    //----------------------------------------------------------------------------
-    
-    private byte[] getHeader(ZipFileIndexEntry entry) throws IOException {
-        zipRandomFile.seek(entry.offset);
-        byte[] header = new byte[30];
-        zipRandomFile.readFully(header);
-        if (get4ByteLittleEndian(header, 0) != 0x04034b50)
-            throw new ZipException("corrupted zip file");
-        if ((get2ByteLittleEndian(header, 6) & 1) != 0)
-            throw new ZipException("encrypted zip file"); // offset 6 in the header of the ZipFileEntry
-        return header;
-    }
-    
-  /*
-   * Inflate using the java.util.zip.Inflater class
-   */
-    private static Inflater inflater;
-    private int inflate(byte[] src, byte[] dest) {
-        
-        // construct the inflater object or reuse an existing one
-        if (inflater == null)
-            inflater = new Inflater(true);
-        
-        synchronized (inflater) {
-            inflater.reset();
-            inflater.setInput(src);
-            try {
-                return inflater.inflate(dest);
-            } catch (DataFormatException ex) {
-                return -1;
-            }
-        }
-    }
-    
-    /**
-     * return the two bytes buf[pos], buf[pos+1] as an unsigned integer in little
-     * endian format.
-     */
-    private static int get2ByteLittleEndian(byte[] buf, int pos) {
-        return (buf[pos] & 0xFF) + ((buf[pos+1] & 0xFF) << 8);
-    }
-    
-    /**
-     * return the 4 bytes buf[i..i+3] as an integer in little endian format.
-     */
-    private static int get4ByteLittleEndian(byte[] buf, int pos) {
-        return (buf[pos] & 0xFF) + ((buf[pos + 1] & 0xFF) << 8) +
-                ((buf[pos + 2] & 0xFF) << 16) + ((buf[pos + 3] & 0xFF) << 24);
-    }
-    
-    /* ----------------------------------------------------------------------------
-     * ZipDirectory
-     * ----------------------------------------------------------------------------*/
-    
-    private class ZipDirectory {
-        private String lastDir;
-        private int lastStart;
-        private int lastLen;
-        
-        byte[] zipDir;
-        RandomAccessFile zipRandomFile = null;
-        ZipFileIndex zipFileIndex = null;
-        
-        public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException {
-            this.zipRandomFile = zipRandomFile;
-            this.zipFileIndex = index;
-            
-            findCENRecord(start, end);
-        }
-        
-        /*
-         * Reads zip file central directory.
-         * For more details see readCEN in zip_util.c from the JDK sources.
-         * This is a Java port of that function.
-         */
-        private void findCENRecord(long start, long end) throws IOException {
-            long totalLength = end - start;
-            int endbuflen = 1024;
-            byte[] endbuf = new byte[endbuflen];
-            long endbufend = end - start;
-            
-            // There is a variable-length field after the dir offset record. We need to do consequential search.
-            while (endbufend >= 22) {
-                if (endbufend < endbuflen)
-                    endbuflen = (int)endbufend;
-                long endbufpos = endbufend - endbuflen;
-                zipRandomFile.seek(start + endbufpos);
-                zipRandomFile.readFully(endbuf, 0, endbuflen);
-                int i = endbuflen - 22;
-                while (i >= 0 &&
-                        !(endbuf[i] == 0x50 &&
-                        endbuf[i + 1] == 0x4b &&
-                        endbuf[i + 2] == 0x05 &&
-                        endbuf[i + 3] == 0x06 &&
-                        endbufpos + i + 22 +
-                        get2ByteLittleEndian(endbuf, i + 20) == totalLength)) {
-                    i--;
-                }
-                
-                if (i >= 0) {
-                    zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2];
-                    zipDir[0] = endbuf[i + 10];
-                    zipDir[1] = endbuf[i + 11];
-                    zipRandomFile.seek(start + get4ByteLittleEndian(endbuf, i + 16));
-                    zipRandomFile.readFully(zipDir, 2, zipDir.length - 2);
-                    return;
-                } else {
-                    endbufend = endbufpos + 21;
-                }
-            }
-            throw new ZipException("cannot read zip file");
-        }
-        private void buildIndex() throws IOException {
-            int entryCount = get2ByteLittleEndian(zipDir, 0);
-            
-            entries = new ZipFileIndexEntry[entryCount];
-            // Add each of the files
-            if (entryCount > 0) {
-                directories = new HashMap<String, DirectoryEntry>();
-                ArrayList<ZipFileIndexEntry> entryList = new ArrayList<ZipFileIndexEntry>();
-                int pos = 2;
-                for (int i = 0; i < entryCount; i++) {
-                    pos = readEntry(pos, entryList, directories);
-                }
-                
-                // Add the accumulated dirs into the same list
-                Iterator i = directories.keySet().iterator();
-                while (i.hasNext()) {
-                    ZipFileIndexEntry zipFileIndexEntry = new ZipFileIndexEntry( (String) i.next());
-                    zipFileIndexEntry.isDir = true;
-                    entryList.add(zipFileIndexEntry);
-                }
-                
-                entries = entryList.toArray(new ZipFileIndexEntry[entryList.size()]);
-                Arrays.sort(entries);
-            } else {
-                cleanupState();
-            }
-        }
-        
-        private int readEntry(int pos, List<ZipFileIndexEntry> entryList,
-                Map<String, DirectoryEntry> directories) throws IOException {
-            if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) {
-                throw new ZipException("cannot read zip file entry");
-            }
-
-            int dirStart = pos + 46;
-            int fileStart = dirStart;
-            int fileEnd = fileStart + get2ByteLittleEndian(zipDir, pos + 28);
-            
-            if (zipFileIndex.symbolFilePrefixLength != 0 &&
-                    ((fileEnd - fileStart) >= symbolFilePrefixLength)) {
-                dirStart += zipFileIndex.symbolFilePrefixLength;
-               fileStart += zipFileIndex.symbolFilePrefixLength;
-            }
-
-            // Use the OS's path separator. Keep the position of the last one.
-            for (int index = fileStart; index < fileEnd; index++) {
-                byte nextByte = zipDir[index];
-                if (nextByte == (byte)'\\' || nextByte == (byte)'/') {
-                    zipDir[index] = (byte)File.separatorChar;
-                    fileStart = index + 1;
-                }
-            }
-            
-            String directory = null;
-            if (fileStart == dirStart)
-                directory = "";
-            else if (lastDir != null && lastLen == fileStart - dirStart - 1) {
-                int index = lastLen - 1;
-                while (zipDir[lastStart + index] == zipDir[dirStart + index]) {
-                    if (index == 0) {
-                        directory = lastDir;
-                        break;
-                    }
-                    index--;
-                }
-            }
-            
-            // Sub directories
-            if (directory == null) {
-                lastStart = dirStart;
-                lastLen = fileStart - dirStart - 1;
-                
-                directory = new String(zipDir, dirStart, lastLen, "UTF-8").intern();
-                lastDir = directory;
-                
-                // Enter also all the parent directories
-                String tempDirectory = directory;
-
-                while (directories.get(tempDirectory) == null) {
-                    directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex));
-                    int separator = tempDirectory.lastIndexOf(File.separatorChar);
-                    if (separator == -1)
-                        break;
-                    tempDirectory = tempDirectory.substring(0, separator);
-                }
-            }
-            else {
-                directory = directory.intern();
-                if (directories.get(directory) == null) {
-                    directories.put(directory, new DirectoryEntry(directory, zipFileIndex));
-                }
-            }
-            
-            // For each dir create also a file
-            if (fileStart != fileEnd) {
-                ZipFileIndexEntry entry = new ZipFileIndexEntry(directory,
-                        new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8"));
-
-                entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12));
-                entry.compressedSize = get4ByteLittleEndian(zipDir, pos + 20);
-                entry.size = get4ByteLittleEndian(zipDir, pos + 24);
-                entry.offset = get4ByteLittleEndian(zipDir, pos + 42);
-                entryList.add(entry);
-            }
-            
-            return pos + 46 +
-                    get2ByteLittleEndian(zipDir, pos + 28) +
-                    get2ByteLittleEndian(zipDir, pos + 30) +
-                    get2ByteLittleEndian(zipDir, pos + 32);
-        }
-    }
-    
-    /**
-     * Returns the last modified timestamp of a zip file.
-     * @return long
-     */
-    public long getZipFileLastModified() throws IOException {
-        lock.lock();
-        try {
-            checkIndex();
-            return zipFileLastModified;
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    /** ------------------------------------------------------------------------
-     *  DirectoryEntry class
-     * -------------------------------------------------------------------------*/
-    static class DirectoryEntry {
-        private boolean filesInited;
-        private boolean directoriesInited;
-        private boolean zipFileEntriesInited;
-        private boolean entriesInited;
-        
-        private long writtenOffsetOffset = 0;
-        
-        private String dirName;
-        
-        private com.sun.tools.javac.util.List<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil();
-        private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>nil();
-        private com.sun.tools.javac.util.List<ZipFileIndexEntry>  zipFileEntries = com.sun.tools.javac.util.List.<ZipFileIndexEntry>nil();
-        
-        private List<ZipFileIndexEntry> entries = new ArrayList<ZipFileIndexEntry>();
-        
-        private ZipFileIndex zipFileIndex;
-        
-        private int numEntries;
-        
-        DirectoryEntry(String dirName, ZipFileIndex index) {
-        filesInited = false;
-            directoriesInited = false;
-            entriesInited = false;
-            
-            if (File.separatorChar == '/') {
-                dirName.replace('\\', '/');
-            }
-            else {
-                dirName.replace('/', '\\');                                
-            }
-
-            this.dirName = dirName.intern();
-            this.zipFileIndex = index;
-        }
-        
-        private com.sun.tools.javac.util.List<String> getFiles() {
-            if (filesInited) {
-                return zipFileEntriesFiles;
-            }
-            
-            initEntries();
-            
-            for (ZipFileIndexEntry e : entries) {
-                if (!e.isDir) {
-                    zipFileEntriesFiles = zipFileEntriesFiles.append(e.name);
-                }
-            }
-            filesInited = true;
-            return zipFileEntriesFiles;
-        }
-        
-        private com.sun.tools.javac.util.List<String> getDirectories() {
-            if (directoriesInited) {
-                return zipFileEntriesFiles;
-            }
-            
-            initEntries();
-            
-            for (ZipFileIndexEntry e : entries) {
-                if (e.isDir) {
-                    zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name);
-                }
-            }
-            
-            directoriesInited = true;
-            
-            return zipFileEntriesDirectories;
-        }
-        
-        private com.sun.tools.javac.util.List<ZipFileIndexEntry> getEntries() {
-            if (zipFileEntriesInited) {
-                return zipFileEntries;
-            }
-            
-            initEntries();
-            
-            zipFileEntries = com.sun.tools.javac.util.List.nil();
-            for (ZipFileIndexEntry zfie : entries) {
-                zipFileEntries = zipFileEntries.append(zfie);
-            }
-            
-            zipFileEntriesInited = true;
-            
-            return zipFileEntries;
-        }
-        
-        private ZipFileIndexEntry getEntry(String rootName) {
-            initEntries();
-            int index = Collections.binarySearch(entries, new ZipFileIndexEntry(dirName, rootName));
-            if (index < 0) {
-                return null;
-            }
-            
-            return entries.get(index);
-        }
-        
-        private void initEntries() {
-            if (entriesInited) {
-                return;
-            }
-            
-            if (!zipFileIndex.readFromIndex) {
-                int from = -Arrays.binarySearch(zipFileIndex.entries,
-                        new ZipFileIndexEntry(dirName, ZipFileIndex.MIN_CHAR)) - 1;
-                int to = -Arrays.binarySearch(zipFileIndex.entries,
-                        new ZipFileIndexEntry(dirName, MAX_CHAR)) - 1;
-                
-                boolean emptyList = false;
-                
-                for (int i = from; i < to; i++) {
-                    entries.add(zipFileIndex.entries[i]);
-                }
-            } else {
-                File indexFile = zipFileIndex.getIndexFile();
-                if (indexFile != null) {
-                    RandomAccessFile raf = null;
-                    try {
-                        raf = new RandomAccessFile(indexFile, "r");
-                        raf.seek(writtenOffsetOffset);
-                        
-                        for (int nFiles = 0; nFiles < numEntries; nFiles++) {
-                            // Read the name bytes
-                            int zfieNameBytesLen = raf.readInt();
-                            byte [] zfieNameBytes = new byte[zfieNameBytesLen];
-                            raf.read(zfieNameBytes);
-                            String eName = new String(zfieNameBytes, "UTF-8");
-                            
-                            // Read isDir
-                            boolean eIsDir = raf.readByte() == (byte)0 ? false : true;
-                            
-                            // Read offset of bytes in the real Jar/Zip file
-                            int eOffset = raf.readInt();
-                            
-                            // Read size of the file in the real Jar/Zip file
-                            int eSize = raf.readInt();
-                            
-                            // Read compressed size of the file in the real Jar/Zip file
-                            int eCsize = raf.readInt();
-                            
-                            // Read java time stamp of the file in the real Jar/Zip file
-                            long eJavaTimestamp = raf.readLong();
-
-                            ZipFileIndexEntry rfie = new ZipFileIndexEntry(dirName, eName);
-                            rfie.isDir = eIsDir;
-                            rfie.offset = eOffset;
-                            rfie.size = eSize;
-                            rfie.compressedSize = eCsize;
-                            rfie.javatime = eJavaTimestamp;
-                            entries.add(rfie);
-                        }
-                    } catch (Throwable t) {
-                        // Do nothing
-                    } finally {
-                        try {
-                            if (raf == null) {
-                                raf.close();
-                            }
-                        } catch (Throwable t) {
-                            // Do nothing
-                        }
-                    }
-                }
-            }
-            
-            entriesInited = true;
-        }
-        
-        List<ZipFileIndexEntry> getEntriesAsCollection() {
-            initEntries();
-            
-            return entries;
-        }
-    }
-    
-    private boolean readIndex() {
-        if (triedToReadIndex || !usePreindexedCache) {
-            return false;
-        }
-        
-        boolean ret = false;
-        lock.lock();
-        try {        
-            triedToReadIndex = true;
-            RandomAccessFile raf = null;
-            try {
-                File indexFileName = getIndexFile();
-                raf = new RandomAccessFile(indexFileName, "r");
-            
-                long fileStamp = raf.readLong();
-                if (zipFile.lastModified() != fileStamp) {
-                    ret = false;
-                } else {
-                    directories = new HashMap<String, DirectoryEntry>();
-                    int numDirs = raf.readInt();
-                    for (int nDirs = 0; nDirs < numDirs; nDirs++) {
-                        int dirNameBytesLen = raf.readInt();
-                        byte [] dirNameBytes = new byte[dirNameBytesLen];
-                        raf.read(dirNameBytes);
-                    
-                        String dirNameStr = new String(dirNameBytes, "UTF-8");
-                        DirectoryEntry de = new DirectoryEntry(dirNameStr, this);
-                        de.numEntries = raf.readInt();
-                        de.writtenOffsetOffset = raf.readLong();
-                        directories.put(dirNameStr, de);
-                    }
-                    ret = true;
-                    zipFileLastModified = fileStamp;
-                }
-            } catch (Throwable t) {
-                // Do nothing
-            } finally {
-                if (raf != null) {
-                    try {
-                        raf.close();
-                    } catch (Throwable tt) {
-                        // Do nothing
-                    }
-                }
-            }
-            if (ret == true) {
-                readFromIndex = true;
-            }
-        }
-        finally {
-            lock.unlock();
-        }
-        
-        return ret;
-    }
-    
-    private boolean writeIndex() {
-        boolean ret = false;
-        if (readFromIndex || !usePreindexedCache) {
-            return true;
-        }
-        
-        if (!writeIndex) {
-            return true;
-        }
-        
-        File indexFile = getIndexFile();
-        if (indexFile == null) {
-            return false;
-        }
-        
-        RandomAccessFile raf = null;
-        long writtenSoFar = 0;
-        try {
-            raf = new RandomAccessFile(indexFile, "rw");
-            
-            raf.writeLong(zipFileLastModified);
-            writtenSoFar += 8;
-            
-            
-            Iterator<String> iterDirName = directories.keySet().iterator();
-            List<DirectoryEntry> directoriesToWrite = new ArrayList<DirectoryEntry>();
-            Map<String, Long> offsets = new HashMap<String, Long>();
-            raf.writeInt(directories.keySet().size());
-            writtenSoFar += 4;
-            
-            while(iterDirName.hasNext()) {
-                String dirName = iterDirName.next();
-                DirectoryEntry dirEntry = directories.get(dirName);
-                
-                directoriesToWrite.add(dirEntry);
-                
-                // Write the dir name bytes
-                byte [] dirNameBytes = dirName.getBytes("UTF-8");
-                int dirNameBytesLen = dirNameBytes.length;
-                raf.writeInt(dirNameBytesLen);
-                writtenSoFar += 4;
-                
-                raf.write(dirNameBytes);
-                writtenSoFar += dirNameBytesLen;
-                
-                // Write the number of files in the dir
-                List dirEntries = dirEntry.getEntriesAsCollection();
-                raf.writeInt(dirEntries.size());
-                writtenSoFar += 4;
-                
-                offsets.put(dirName, new Long(writtenSoFar));
-                
-                // Write the offset of the file's data in the dir
-                dirEntry.writtenOffsetOffset = 0L;
-                raf.writeLong(0L);
-                writtenSoFar += 8;
-            }
-            
-            for (DirectoryEntry de : directoriesToWrite) {
-                // Fix up the offset in the directory table
-                long currFP = raf.getFilePointer();
-                
-                long offsetOffset = offsets.get(de.dirName).longValue();
-                raf.seek(offsetOffset);
-                raf.writeLong(writtenSoFar);
-                
-                raf.seek(currFP);
-                
-                // Now write each of the files in the DirectoryEntry
-                List<ZipFileIndexEntry> entries = de.getEntriesAsCollection();
-                for (ZipFileIndexEntry zfie : entries) {
-                    // Write the name bytes
-                    byte [] zfieNameBytes = zfie.name.getBytes("UTF-8");
-                    int zfieNameBytesLen = zfieNameBytes.length;
-                    raf.writeInt(zfieNameBytesLen);
-                    writtenSoFar += 4;
-                    raf.write(zfieNameBytes);
-                    writtenSoFar += zfieNameBytesLen;
-                    
-                    // Write isDir
-                    raf.writeByte(zfie.isDir ? (byte)1 : (byte)0);
-                    writtenSoFar += 1;
-                    
-                    // Write offset of bytes in the real Jar/Zip file
-                    raf.writeInt(zfie.offset);
-                    writtenSoFar += 4;
-                    
-                    // Write size of the file in the real Jar/Zip file
-                    raf.writeInt(zfie.size);
-                    writtenSoFar += 4;
-                    
-                    // Write compressed size of the file in the real Jar/Zip file
-                    raf.writeInt(zfie.compressedSize);
-                    writtenSoFar += 4;
-                    
-                    // Write java time stamp of the file in the real Jar/Zip file
-                    raf.writeLong(zfie.getLastModified());
-                    writtenSoFar += 8;
-                }
-            }
-        } catch (Throwable t) {
-            // Do nothing
-        } finally {
-            try {
-                if (raf != null) {
-                    raf.close();
-                }
-            } catch(IOException ioe) {
-                // Do nothing
-            }
-        }
-
-        return ret;
-    }
-    
-    public boolean writeZipIndex() {
-        lock.lock();
-        try {
-            return writeIndex();
-        }
-        finally {
-            lock.unlock();
-        }
-    }
-    
-    private File getIndexFile() {
-        if (zipIndexFile == null) {
-            if (zipFile == null) {
-                return null;
-            }
-            
-            zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
-                    zipFile.getName() + ".index");
-        }
-        
-        return zipIndexFile;
-    }
-    
-    public File getZipFile() {
-        return zipFile;
-    }
-}
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.zip;
+
+import java.io.*;
+import java.text.MessageFormat;
+import java.util.*;
+import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.zip.*;
+
+/** This class implements building of index of a zip archive and access to it's context.
+ *  It also uses prebuild index if available. It supports invocations where it will
+ *  serialize an optimized zip index file to disk.
+ *
+ *  In oreder to use secondary index file make sure the option "usezipindex" is in the Options object,
+ *  when JavacFileManager is invoked. (You can pass "-XDusezipindex" on the command line.
+ *
+ *  Location where to look for/generate optimized zip index files can be provided using
+ *  "-XDcachezipindexdir=<directory>". If this flag is not provided, the dfault location is
+ *  the value of the "java.io.tmpdir" system property.
+ *
+ *  If key "-XDwritezipindexfiles" is specified, there will be new optimized index file
+ *  created for each archive, used by the compiler for compilation, at location,
+ *  specified by "cachezipindexdir" option.
+ *
+ * If nonBatchMode option is specified (-XDnonBatchMode) the compiler will use timestamp
+ * checking to reindex the zip files if it is needed. In batch mode the timestamps are not checked
+ * and the compiler uses the cached indexes.
+ */
+public class ZipFileIndex {
+    private static final String MIN_CHAR = String.valueOf(Character.MIN_VALUE);
+    private static final String MAX_CHAR = String.valueOf(Character.MAX_VALUE);
+
+    public final static long NOT_MODIFIED = Long.MIN_VALUE;
+
+    private static Map<File, ZipFileIndex> zipFileIndexCache = new HashMap<File, ZipFileIndex>();
+    private static ReentrantLock lock = new ReentrantLock();
+
+    private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this.
+
+    private Map<String, DirectoryEntry> directories = Collections.<String, DirectoryEntry>emptyMap();
+    private Set<String> allDirs = Collections.<String>emptySet();
+
+    // ZipFileIndex data entries
+    private File zipFile;
+    private long zipFileLastModified = NOT_MODIFIED;
+    private RandomAccessFile zipRandomFile;
+    private ZipFileIndexEntry[] entries;
+
+    private boolean readFromIndex = false;
+    private File zipIndexFile = null;
+    private boolean triedToReadIndex = false;
+    private int symbolFilePrefixLength = 0;
+    private boolean hasPopulatedData = false;
+    private long lastReferenceTimeStamp = NOT_MODIFIED;
+
+    private boolean usePreindexedCache = false;
+    private String preindexedCacheLocation = null;
+
+    private boolean writeIndex = false;
+
+    /**
+     * Returns a list of all ZipFileIndex entries
+     *
+     * @return A list of ZipFileIndex entries, or an empty list
+     */
+    public static List<ZipFileIndex> getZipFileIndexes() {
+        return getZipFileIndexes(false);
+    }
+
+    /**
+     * Returns a list of all ZipFileIndex entries
+     *
+     * @param openedOnly If true it returns a list of only opened ZipFileIndex entries, otherwise
+     *                   all ZipFileEntry(s) are included into the list.
+     * @return A list of ZipFileIndex entries, or an empty list
+     */
+    public static List<ZipFileIndex> getZipFileIndexes(boolean openedOnly) {
+        List<ZipFileIndex> zipFileIndexes = new ArrayList<ZipFileIndex>();
+        lock.lock();
+        try {
+            zipFileIndexes.addAll(zipFileIndexCache.values());
+
+            if (openedOnly) {
+                for(ZipFileIndex elem : zipFileIndexes) {
+                    if (!elem.isOpen()) {
+                        zipFileIndexes.remove(elem);
+                    }
+                }
+            }
+        }
+        finally {
+            lock.unlock();
+        }
+        return zipFileIndexes;
+    }
+
+    public boolean isOpen() {
+        lock.lock();
+        try {
+            return zipRandomFile != null;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public static ZipFileIndex getZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean useCache, String cacheLocation, boolean writeIndex) throws IOException {
+        ZipFileIndex zi = null;
+        lock.lock();
+        try {
+            zi = getExistingZipIndex(zipFile);
+
+            if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
+                zi = new ZipFileIndex(zipFile, symbolFilePrefixLen, writeIndex,
+                        useCache, cacheLocation);
+                zipFileIndexCache.put(zipFile, zi);
+            }
+        }
+        finally {
+            lock.unlock();
+        }
+        return zi;
+    }
+
+    public static ZipFileIndex getExistingZipIndex(File zipFile) {
+        lock.lock();
+        try {
+            return zipFileIndexCache.get(zipFile);
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public static void clearCache() {
+        lock.lock();
+        try {
+            zipFileIndexCache.clear();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public static void clearCache(long timeNotUsed) {
+        lock.lock();
+        try {
+            Iterator<File> cachedFileIterator = zipFileIndexCache.keySet().iterator();
+            while (cachedFileIterator.hasNext()) {
+                File cachedFile = cachedFileIterator.next();
+                ZipFileIndex cachedZipIndex = zipFileIndexCache.get(cachedFile);
+                if (cachedZipIndex != null) {
+                    long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
+                    if (timeToTest < cachedZipIndex.lastReferenceTimeStamp || // Overflow...
+                            System.currentTimeMillis() > timeToTest) {
+                        zipFileIndexCache.remove(cachedFile);
+                    }
+                }
+            }
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public static void removeFromCache(File file) {
+        lock.lock();
+        try {
+            zipFileIndexCache.remove(file);
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    /** Sets already opened list of ZipFileIndexes from an outside client
+      * of the compiler. This functionality should be used in a non-batch clients of the compiler.
+      */
+    public static void setOpenedIndexes(List<ZipFileIndex>indexes) throws IllegalStateException {
+        lock.lock();
+        try {
+            if (zipFileIndexCache.isEmpty()) {
+                throw new IllegalStateException("Setting opened indexes should be called only when the ZipFileCache is empty. Call JavacFileManager.flush() before calling this method.");
+            }
+
+            for (ZipFileIndex zfi : indexes) {
+                zipFileIndexCache.put(zfi.zipFile, zfi);
+            }
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    private ZipFileIndex(File zipFile, int symbolFilePrefixLen, boolean writeIndex,
+            boolean useCache, String cacheLocation) throws IOException {
+        this.zipFile = zipFile;
+        this.symbolFilePrefixLength = symbolFilePrefixLen;
+        this.writeIndex = writeIndex;
+        this.usePreindexedCache = useCache;
+        this.preindexedCacheLocation = cacheLocation;
+
+        if (zipFile != null) {
+            this.zipFileLastModified = zipFile.lastModified();
+        }
+
+        // Validate integrity of the zip file
+        checkIndex();
+    }
+
+    public String toString() {
+        return "ZipFileIndex of file:(" + zipFile + ")";
+    }
+
+    // Just in case...
+    protected void finalize() {
+        closeFile();
+    }
+
+    private boolean isUpToDate() {
+        if (zipFile != null &&
+                ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified()) &&
+                hasPopulatedData) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Here we need to make sure that the ZipFileIndex is valid. Check the timestamp of the file and
+     * if its the same as the one at the time the index was build we don't need to reopen anything.
+     */
+    private void checkIndex() throws IOException {
+        boolean isUpToDate = true;
+        if (!isUpToDate()) {
+            closeFile();
+            isUpToDate = false;
+        }
+
+        if (zipRandomFile != null || isUpToDate) {
+            lastReferenceTimeStamp = System.currentTimeMillis();
+            return;
+        }
+
+        hasPopulatedData = true;
+
+        if (readIndex()) {
+            lastReferenceTimeStamp = System.currentTimeMillis();
+            return;
+        }
+
+        directories = Collections.<String, DirectoryEntry>emptyMap();
+        allDirs = Collections.<String>emptySet();
+
+        try {
+            openFile();
+            long totalLength = zipRandomFile.length();
+            ZipDirectory directory = new ZipDirectory(zipRandomFile, 0L, totalLength, this);
+            directory.buildIndex();
+        } finally {
+            if (zipRandomFile != null) {
+                closeFile();
+            }
+        }
+
+        lastReferenceTimeStamp = System.currentTimeMillis();
+    }
+
+    private void openFile() throws FileNotFoundException {
+        if (zipRandomFile == null && zipFile != null) {
+            zipRandomFile = new RandomAccessFile(zipFile, "r");
+        }
+    }
+
+    private void cleanupState() {
+        // Make sure there is a valid but empty index if the file doesn't exist
+        entries = ZipFileIndexEntry.EMPTY_ARRAY;
+        directories = Collections.<String, DirectoryEntry>emptyMap();
+        zipFileLastModified = NOT_MODIFIED;
+        allDirs = Collections.<String>emptySet();
+    }
+
+    public void close() {
+        lock.lock();
+        try {
+            writeIndex();
+            closeFile();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    private void closeFile() {
+        if (zipRandomFile != null) {
+            try {
+                zipRandomFile.close();
+            } catch (IOException ex) {
+            }
+            zipRandomFile = null;
+        }
+    }
+
+    /**
+     * Returns the ZipFileIndexEntry for an absolute path, if there is one.
+     */
+    public ZipFileIndexEntry getZipIndexEntry(String path) {
+        if (File.separatorChar != '/') {
+            path = path.replace('/', File.separatorChar);
+        }
+        lock.lock();
+        try {
+            checkIndex();
+            String lookFor = "";
+            int lastSepIndex = path.lastIndexOf(File.separatorChar);
+            boolean noSeparator = false;
+            if (lastSepIndex == -1) {
+                noSeparator = true;
+            }
+
+            DirectoryEntry de = directories.get(noSeparator ? "" : path.substring(0, lastSepIndex));
+
+            lookFor = path.substring(noSeparator ? 0 : lastSepIndex + 1);
+
+            return de == null ? null : de.getEntry(lookFor);
+        }
+        catch (IOException e) {
+            return null;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Returns a javac List of filenames within an absolute path in the ZipFileIndex.
+     */
+    public com.sun.tools.javac.util.List<String> getFiles(String path) {
+        if (File.separatorChar != '/') {
+            path = path.replace('/', File.separatorChar);
+        }
+
+        lock.lock();
+        try {
+            checkIndex();
+
+            DirectoryEntry de = directories.get(path);
+            com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getFiles();
+
+            if (ret == null) {
+                return com.sun.tools.javac.util.List.<String>nil();
+            }
+            return ret;
+        }
+        catch (IOException e) {
+            return com.sun.tools.javac.util.List.<String>nil();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public List<String> getAllDirectories(String path) {
+
+        if (File.separatorChar != '/') {
+            path = path.replace('/', File.separatorChar);
+        }
+
+        lock.lock();
+        try {
+            checkIndex();
+            path = path.intern();
+
+            DirectoryEntry de = directories.get(path);
+            com.sun.tools.javac.util.List<String> ret = de == null ? null : de.getDirectories();
+
+            if (ret == null) {
+                return com.sun.tools.javac.util.List.<String>nil();
+            }
+
+            return ret;
+        }
+        catch (IOException e) {
+            return com.sun.tools.javac.util.List.<String>nil();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public Set<String> getAllDirectories() {
+        lock.lock();
+        try {
+            checkIndex();
+            if (allDirs == Collections.EMPTY_SET) {
+                Set<String> alldirs = new HashSet<String>();
+                Iterator<String> dirsIter = directories.keySet().iterator();
+                while (dirsIter.hasNext()) {
+                    alldirs.add(new String(dirsIter.next()));
+                }
+
+                allDirs = alldirs;
+            }
+
+            return allDirs;
+        }
+        catch (IOException e) {
+            return Collections.<String>emptySet();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    /**
+     * Tests if a specific path exists in the zip.  This method will return true
+     * for file entries and directories.
+     *
+     * @param path A path within the zip.
+     * @return True if the path is a file or dir, false otherwise.
+     */
+    public boolean contains(String path) {
+        lock.lock();
+        try {
+            checkIndex();
+            return getZipIndexEntry(path) != null;
+        }
+        catch (IOException e) {
+            return false;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public boolean isDirectory(String path) throws IOException {
+        lock.lock();
+        try {
+            // The top level in a zip file is always a directory.
+            if (path.length() == 0) {
+                lastReferenceTimeStamp = System.currentTimeMillis();
+                return true;
+            }
+
+            if (File.separatorChar != '/')
+                path = path.replace('/', File.separatorChar);
+            checkIndex();
+            return directories.get(path) != null;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public long getLastModified(String path) throws IOException {
+        lock.lock();
+        try {
+            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            if (entry == null)
+                throw new FileNotFoundException();
+            return entry.getLastModified();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public int length(String path) throws IOException {
+        lock.lock();
+        try {
+            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            if (entry == null)
+                throw new FileNotFoundException();
+
+            if (entry.isDir) {
+                return 0;
+            }
+
+            byte[] header = getHeader(entry);
+            // entry is not compressed?
+            if (get2ByteLittleEndian(header, 8) == 0) {
+                return entry.compressedSize;
+            } else {
+                return entry.size;
+            }
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public byte[] read(String path) throws IOException {
+        lock.lock();
+        try {
+            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            if (entry == null)
+                throw new FileNotFoundException(MessageFormat.format("Path not found in ZIP: {0}", path));
+            return read(entry);
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public byte[] read(ZipFileIndexEntry entry) throws IOException {
+        lock.lock();
+        try {
+            openFile();
+            byte[] result = readBytes(entry);
+            closeFile();
+            return result;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public int read(String path, byte[] buffer) throws IOException {
+        lock.lock();
+        try {
+            ZipFileIndexEntry entry = getZipIndexEntry(path);
+            if (entry == null)
+                throw new FileNotFoundException();
+            return read(entry, buffer);
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    public int read(ZipFileIndexEntry entry, byte[] buffer)
+            throws IOException {
+        lock.lock();
+        try {
+            int result = readBytes(entry, buffer);
+            return result;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    private byte[] readBytes(ZipFileIndexEntry entry) throws IOException {
+        byte[] header = getHeader(entry);
+        int csize = entry.compressedSize;
+        byte[] cbuf = new byte[csize];
+        zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28));
+        zipRandomFile.readFully(cbuf, 0, csize);
+
+        // is this compressed - offset 8 in the ZipEntry header
+        if (get2ByteLittleEndian(header, 8) == 0)
+            return cbuf;
+
+        int size = entry.size;
+        byte[] buf = new byte[size];
+        if (inflate(cbuf, buf) != size)
+            throw new ZipException("corrupted zip file");
+
+        return buf;
+    }
+
+    /**
+     *
+     */
+    private int readBytes(ZipFileIndexEntry entry, byte[] buffer) throws IOException {
+        byte[] header = getHeader(entry);
+
+        // entry is not compressed?
+        if (get2ByteLittleEndian(header, 8) == 0) {
+            zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28));
+            int offset = 0;
+            int size = buffer.length;
+            while (offset < size) {
+                int count = zipRandomFile.read(buffer, offset, size - offset);
+                if (count == -1)
+                    break;
+                offset += count;
+            }
+            return entry.size;
+        }
+
+        int csize = entry.compressedSize;
+        byte[] cbuf = new byte[csize];
+        zipRandomFile.skipBytes(get2ByteLittleEndian(header, 26) + get2ByteLittleEndian(header, 28));
+        zipRandomFile.readFully(cbuf, 0, csize);
+
+        int count = inflate(cbuf, buffer);
+        if (count == -1)
+            throw new ZipException("corrupted zip file");
+
+        return entry.size;
+    }
+
+    //----------------------------------------------------------------------------
+    // Zip utilities
+    //----------------------------------------------------------------------------
+
+    private byte[] getHeader(ZipFileIndexEntry entry) throws IOException {
+        zipRandomFile.seek(entry.offset);
+        byte[] header = new byte[30];
+        zipRandomFile.readFully(header);
+        if (get4ByteLittleEndian(header, 0) != 0x04034b50)
+            throw new ZipException("corrupted zip file");
+        if ((get2ByteLittleEndian(header, 6) & 1) != 0)
+            throw new ZipException("encrypted zip file"); // offset 6 in the header of the ZipFileEntry
+        return header;
+    }
+
+  /*
+   * Inflate using the java.util.zip.Inflater class
+   */
+    private static Inflater inflater;
+    private int inflate(byte[] src, byte[] dest) {
+
+        // construct the inflater object or reuse an existing one
+        if (inflater == null)
+            inflater = new Inflater(true);
+
+        synchronized (inflater) {
+            inflater.reset();
+            inflater.setInput(src);
+            try {
+                return inflater.inflate(dest);
+            } catch (DataFormatException ex) {
+                return -1;
+            }
+        }
+    }
+
+    /**
+     * return the two bytes buf[pos], buf[pos+1] as an unsigned integer in little
+     * endian format.
+     */
+    private static int get2ByteLittleEndian(byte[] buf, int pos) {
+        return (buf[pos] & 0xFF) + ((buf[pos+1] & 0xFF) << 8);
+    }
+
+    /**
+     * return the 4 bytes buf[i..i+3] as an integer in little endian format.
+     */
+    private static int get4ByteLittleEndian(byte[] buf, int pos) {
+        return (buf[pos] & 0xFF) + ((buf[pos + 1] & 0xFF) << 8) +
+                ((buf[pos + 2] & 0xFF) << 16) + ((buf[pos + 3] & 0xFF) << 24);
+    }
+
+    /* ----------------------------------------------------------------------------
+     * ZipDirectory
+     * ----------------------------------------------------------------------------*/
+
+    private class ZipDirectory {
+        private String lastDir;
+        private int lastStart;
+        private int lastLen;
+
+        byte[] zipDir;
+        RandomAccessFile zipRandomFile = null;
+        ZipFileIndex zipFileIndex = null;
+
+        public ZipDirectory(RandomAccessFile zipRandomFile, long start, long end, ZipFileIndex index) throws IOException {
+            this.zipRandomFile = zipRandomFile;
+            this.zipFileIndex = index;
+
+            findCENRecord(start, end);
+        }
+
+        /*
+         * Reads zip file central directory.
+         * For more details see readCEN in zip_util.c from the JDK sources.
+         * This is a Java port of that function.
+         */
+        private void findCENRecord(long start, long end) throws IOException {
+            long totalLength = end - start;
+            int endbuflen = 1024;
+            byte[] endbuf = new byte[endbuflen];
+            long endbufend = end - start;
+
+            // There is a variable-length field after the dir offset record. We need to do consequential search.
+            while (endbufend >= 22) {
+                if (endbufend < endbuflen)
+                    endbuflen = (int)endbufend;
+                long endbufpos = endbufend - endbuflen;
+                zipRandomFile.seek(start + endbufpos);
+                zipRandomFile.readFully(endbuf, 0, endbuflen);
+                int i = endbuflen - 22;
+                while (i >= 0 &&
+                        !(endbuf[i] == 0x50 &&
+                        endbuf[i + 1] == 0x4b &&
+                        endbuf[i + 2] == 0x05 &&
+                        endbuf[i + 3] == 0x06 &&
+                        endbufpos + i + 22 +
+                        get2ByteLittleEndian(endbuf, i + 20) == totalLength)) {
+                    i--;
+                }
+
+                if (i >= 0) {
+                    zipDir = new byte[get4ByteLittleEndian(endbuf, i + 12) + 2];
+                    zipDir[0] = endbuf[i + 10];
+                    zipDir[1] = endbuf[i + 11];
+                    zipRandomFile.seek(start + get4ByteLittleEndian(endbuf, i + 16));
+                    zipRandomFile.readFully(zipDir, 2, zipDir.length - 2);
+                    return;
+                } else {
+                    endbufend = endbufpos + 21;
+                }
+            }
+            throw new ZipException("cannot read zip file");
+        }
+        private void buildIndex() throws IOException {
+            int entryCount = get2ByteLittleEndian(zipDir, 0);
+
+            entries = new ZipFileIndexEntry[entryCount];
+            // Add each of the files
+            if (entryCount > 0) {
+                directories = new HashMap<String, DirectoryEntry>();
+                ArrayList<ZipFileIndexEntry> entryList = new ArrayList<ZipFileIndexEntry>();
+                int pos = 2;
+                for (int i = 0; i < entryCount; i++) {
+                    pos = readEntry(pos, entryList, directories);
+                }
+
+                // Add the accumulated dirs into the same list
+                Iterator i = directories.keySet().iterator();
+                while (i.hasNext()) {
+                    ZipFileIndexEntry zipFileIndexEntry = new ZipFileIndexEntry( (String) i.next());
+                    zipFileIndexEntry.isDir = true;
+                    entryList.add(zipFileIndexEntry);
+                }
+
+                entries = entryList.toArray(new ZipFileIndexEntry[entryList.size()]);
+                Arrays.sort(entries);
+            } else {
+                cleanupState();
+            }
+        }
+
+        private int readEntry(int pos, List<ZipFileIndexEntry> entryList,
+                Map<String, DirectoryEntry> directories) throws IOException {
+            if (get4ByteLittleEndian(zipDir, pos) != 0x02014b50) {
+                throw new ZipException("cannot read zip file entry");
+            }
+
+            int dirStart = pos + 46;
+            int fileStart = dirStart;
+            int fileEnd = fileStart + get2ByteLittleEndian(zipDir, pos + 28);
+
+            if (zipFileIndex.symbolFilePrefixLength != 0 &&
+                    ((fileEnd - fileStart) >= symbolFilePrefixLength)) {
+                dirStart += zipFileIndex.symbolFilePrefixLength;
+               fileStart += zipFileIndex.symbolFilePrefixLength;
+            }
+
+            // Use the OS's path separator. Keep the position of the last one.
+            for (int index = fileStart; index < fileEnd; index++) {
+                byte nextByte = zipDir[index];
+                if (nextByte == (byte)'\\' || nextByte == (byte)'/') {
+                    zipDir[index] = (byte)File.separatorChar;
+                    fileStart = index + 1;
+                }
+            }
+
+            String directory = null;
+            if (fileStart == dirStart)
+                directory = "";
+            else if (lastDir != null && lastLen == fileStart - dirStart - 1) {
+                int index = lastLen - 1;
+                while (zipDir[lastStart + index] == zipDir[dirStart + index]) {
+                    if (index == 0) {
+                        directory = lastDir;
+                        break;
+                    }
+                    index--;
+                }
+            }
+
+            // Sub directories
+            if (directory == null) {
+                lastStart = dirStart;
+                lastLen = fileStart - dirStart - 1;
+
+                directory = new String(zipDir, dirStart, lastLen, "UTF-8").intern();
+                lastDir = directory;
+
+                // Enter also all the parent directories
+                String tempDirectory = directory;
+
+                while (directories.get(tempDirectory) == null) {
+                    directories.put(tempDirectory, new DirectoryEntry(tempDirectory, zipFileIndex));
+                    int separator = tempDirectory.lastIndexOf(File.separatorChar);
+                    if (separator == -1)
+                        break;
+                    tempDirectory = tempDirectory.substring(0, separator);
+                }
+            }
+            else {
+                directory = directory.intern();
+                if (directories.get(directory) == null) {
+                    directories.put(directory, new DirectoryEntry(directory, zipFileIndex));
+                }
+            }
+
+            // For each dir create also a file
+            if (fileStart != fileEnd) {
+                ZipFileIndexEntry entry = new ZipFileIndexEntry(directory,
+                        new String(zipDir, fileStart, fileEnd - fileStart, "UTF-8"));
+
+                entry.setNativeTime(get4ByteLittleEndian(zipDir, pos + 12));
+                entry.compressedSize = get4ByteLittleEndian(zipDir, pos + 20);
+                entry.size = get4ByteLittleEndian(zipDir, pos + 24);
+                entry.offset = get4ByteLittleEndian(zipDir, pos + 42);
+                entryList.add(entry);
+            }
+
+            return pos + 46 +
+                    get2ByteLittleEndian(zipDir, pos + 28) +
+                    get2ByteLittleEndian(zipDir, pos + 30) +
+                    get2ByteLittleEndian(zipDir, pos + 32);
+        }
+    }
+
+    /**
+     * Returns the last modified timestamp of a zip file.
+     * @return long
+     */
+    public long getZipFileLastModified() throws IOException {
+        lock.lock();
+        try {
+            checkIndex();
+            return zipFileLastModified;
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    /** ------------------------------------------------------------------------
+     *  DirectoryEntry class
+     * -------------------------------------------------------------------------*/
+    static class DirectoryEntry {
+        private boolean filesInited;
+        private boolean directoriesInited;
+        private boolean zipFileEntriesInited;
+        private boolean entriesInited;
+
+        private long writtenOffsetOffset = 0;
+
+        private String dirName;
+
+        private com.sun.tools.javac.util.List<String> zipFileEntriesFiles = com.sun.tools.javac.util.List.<String>nil();
+        private com.sun.tools.javac.util.List<String> zipFileEntriesDirectories = com.sun.tools.javac.util.List.<String>nil();
+        private com.sun.tools.javac.util.List<ZipFileIndexEntry>  zipFileEntries = com.sun.tools.javac.util.List.<ZipFileIndexEntry>nil();
+
+        private List<ZipFileIndexEntry> entries = new ArrayList<ZipFileIndexEntry>();
+
+        private ZipFileIndex zipFileIndex;
+
+        private int numEntries;
+
+        DirectoryEntry(String dirName, ZipFileIndex index) {
+        filesInited = false;
+            directoriesInited = false;
+            entriesInited = false;
+
+            if (File.separatorChar == '/') {
+                dirName.replace('\\', '/');
+            }
+            else {
+                dirName.replace('/', '\\');
+            }
+
+            this.dirName = dirName.intern();
+            this.zipFileIndex = index;
+        }
+
+        private com.sun.tools.javac.util.List<String> getFiles() {
+            if (filesInited) {
+                return zipFileEntriesFiles;
+            }
+
+            initEntries();
+
+            for (ZipFileIndexEntry e : entries) {
+                if (!e.isDir) {
+                    zipFileEntriesFiles = zipFileEntriesFiles.append(e.name);
+                }
+            }
+            filesInited = true;
+            return zipFileEntriesFiles;
+        }
+
+        private com.sun.tools.javac.util.List<String> getDirectories() {
+            if (directoriesInited) {
+                return zipFileEntriesFiles;
+            }
+
+            initEntries();
+
+            for (ZipFileIndexEntry e : entries) {
+                if (e.isDir) {
+                    zipFileEntriesDirectories = zipFileEntriesDirectories.append(e.name);
+                }
+            }
+
+            directoriesInited = true;
+
+            return zipFileEntriesDirectories;
+        }
+
+        private com.sun.tools.javac.util.List<ZipFileIndexEntry> getEntries() {
+            if (zipFileEntriesInited) {
+                return zipFileEntries;
+            }
+
+            initEntries();
+
+            zipFileEntries = com.sun.tools.javac.util.List.nil();
+            for (ZipFileIndexEntry zfie : entries) {
+                zipFileEntries = zipFileEntries.append(zfie);
+            }
+
+            zipFileEntriesInited = true;
+
+            return zipFileEntries;
+        }
+
+        private ZipFileIndexEntry getEntry(String rootName) {
+            initEntries();
+            int index = Collections.binarySearch(entries, new ZipFileIndexEntry(dirName, rootName));
+            if (index < 0) {
+                return null;
+            }
+
+            return entries.get(index);
+        }
+
+        private void initEntries() {
+            if (entriesInited) {
+                return;
+            }
+
+            if (!zipFileIndex.readFromIndex) {
+                int from = -Arrays.binarySearch(zipFileIndex.entries,
+                        new ZipFileIndexEntry(dirName, ZipFileIndex.MIN_CHAR)) - 1;
+                int to = -Arrays.binarySearch(zipFileIndex.entries,
+                        new ZipFileIndexEntry(dirName, MAX_CHAR)) - 1;
+
+                boolean emptyList = false;
+
+                for (int i = from; i < to; i++) {
+                    entries.add(zipFileIndex.entries[i]);
+                }
+            } else {
+                File indexFile = zipFileIndex.getIndexFile();
+                if (indexFile != null) {
+                    RandomAccessFile raf = null;
+                    try {
+                        raf = new RandomAccessFile(indexFile, "r");
+                        raf.seek(writtenOffsetOffset);
+
+                        for (int nFiles = 0; nFiles < numEntries; nFiles++) {
+                            // Read the name bytes
+                            int zfieNameBytesLen = raf.readInt();
+                            byte [] zfieNameBytes = new byte[zfieNameBytesLen];
+                            raf.read(zfieNameBytes);
+                            String eName = new String(zfieNameBytes, "UTF-8");
+
+                            // Read isDir
+                            boolean eIsDir = raf.readByte() == (byte)0 ? false : true;
+
+                            // Read offset of bytes in the real Jar/Zip file
+                            int eOffset = raf.readInt();
+
+                            // Read size of the file in the real Jar/Zip file
+                            int eSize = raf.readInt();
+
+                            // Read compressed size of the file in the real Jar/Zip file
+                            int eCsize = raf.readInt();
+
+                            // Read java time stamp of the file in the real Jar/Zip file
+                            long eJavaTimestamp = raf.readLong();
+
+                            ZipFileIndexEntry rfie = new ZipFileIndexEntry(dirName, eName);
+                            rfie.isDir = eIsDir;
+                            rfie.offset = eOffset;
+                            rfie.size = eSize;
+                            rfie.compressedSize = eCsize;
+                            rfie.javatime = eJavaTimestamp;
+                            entries.add(rfie);
+                        }
+                    } catch (Throwable t) {
+                        // Do nothing
+                    } finally {
+                        try {
+                            if (raf == null) {
+                                raf.close();
+                            }
+                        } catch (Throwable t) {
+                            // Do nothing
+                        }
+                    }
+                }
+            }
+
+            entriesInited = true;
+        }
+
+        List<ZipFileIndexEntry> getEntriesAsCollection() {
+            initEntries();
+
+            return entries;
+        }
+    }
+
+    private boolean readIndex() {
+        if (triedToReadIndex || !usePreindexedCache) {
+            return false;
+        }
+
+        boolean ret = false;
+        lock.lock();
+        try {
+            triedToReadIndex = true;
+            RandomAccessFile raf = null;
+            try {
+                File indexFileName = getIndexFile();
+                raf = new RandomAccessFile(indexFileName, "r");
+
+                long fileStamp = raf.readLong();
+                if (zipFile.lastModified() != fileStamp) {
+                    ret = false;
+                } else {
+                    directories = new HashMap<String, DirectoryEntry>();
+                    int numDirs = raf.readInt();
+                    for (int nDirs = 0; nDirs < numDirs; nDirs++) {
+                        int dirNameBytesLen = raf.readInt();
+                        byte [] dirNameBytes = new byte[dirNameBytesLen];
+                        raf.read(dirNameBytes);
+
+                        String dirNameStr = new String(dirNameBytes, "UTF-8");
+                        DirectoryEntry de = new DirectoryEntry(dirNameStr, this);
+                        de.numEntries = raf.readInt();
+                        de.writtenOffsetOffset = raf.readLong();
+                        directories.put(dirNameStr, de);
+                    }
+                    ret = true;
+                    zipFileLastModified = fileStamp;
+                }
+            } catch (Throwable t) {
+                // Do nothing
+            } finally {
+                if (raf != null) {
+                    try {
+                        raf.close();
+                    } catch (Throwable tt) {
+                        // Do nothing
+                    }
+                }
+            }
+            if (ret == true) {
+                readFromIndex = true;
+            }
+        }
+        finally {
+            lock.unlock();
+        }
+
+        return ret;
+    }
+
+    private boolean writeIndex() {
+        boolean ret = false;
+        if (readFromIndex || !usePreindexedCache) {
+            return true;
+        }
+
+        if (!writeIndex) {
+            return true;
+        }
+
+        File indexFile = getIndexFile();
+        if (indexFile == null) {
+            return false;
+        }
+
+        RandomAccessFile raf = null;
+        long writtenSoFar = 0;
+        try {
+            raf = new RandomAccessFile(indexFile, "rw");
+
+            raf.writeLong(zipFileLastModified);
+            writtenSoFar += 8;
+
+
+            Iterator<String> iterDirName = directories.keySet().iterator();
+            List<DirectoryEntry> directoriesToWrite = new ArrayList<DirectoryEntry>();
+            Map<String, Long> offsets = new HashMap<String, Long>();
+            raf.writeInt(directories.keySet().size());
+            writtenSoFar += 4;
+
+            while(iterDirName.hasNext()) {
+                String dirName = iterDirName.next();
+                DirectoryEntry dirEntry = directories.get(dirName);
+
+                directoriesToWrite.add(dirEntry);
+
+                // Write the dir name bytes
+                byte [] dirNameBytes = dirName.getBytes("UTF-8");
+                int dirNameBytesLen = dirNameBytes.length;
+                raf.writeInt(dirNameBytesLen);
+                writtenSoFar += 4;
+
+                raf.write(dirNameBytes);
+                writtenSoFar += dirNameBytesLen;
+
+                // Write the number of files in the dir
+                List dirEntries = dirEntry.getEntriesAsCollection();
+                raf.writeInt(dirEntries.size());
+                writtenSoFar += 4;
+
+                offsets.put(dirName, new Long(writtenSoFar));
+
+                // Write the offset of the file's data in the dir
+                dirEntry.writtenOffsetOffset = 0L;
+                raf.writeLong(0L);
+                writtenSoFar += 8;
+            }
+
+            for (DirectoryEntry de : directoriesToWrite) {
+                // Fix up the offset in the directory table
+                long currFP = raf.getFilePointer();
+
+                long offsetOffset = offsets.get(de.dirName).longValue();
+                raf.seek(offsetOffset);
+                raf.writeLong(writtenSoFar);
+
+                raf.seek(currFP);
+
+                // Now write each of the files in the DirectoryEntry
+                List<ZipFileIndexEntry> entries = de.getEntriesAsCollection();
+                for (ZipFileIndexEntry zfie : entries) {
+                    // Write the name bytes
+                    byte [] zfieNameBytes = zfie.name.getBytes("UTF-8");
+                    int zfieNameBytesLen = zfieNameBytes.length;
+                    raf.writeInt(zfieNameBytesLen);
+                    writtenSoFar += 4;
+                    raf.write(zfieNameBytes);
+                    writtenSoFar += zfieNameBytesLen;
+
+                    // Write isDir
+                    raf.writeByte(zfie.isDir ? (byte)1 : (byte)0);
+                    writtenSoFar += 1;
+
+                    // Write offset of bytes in the real Jar/Zip file
+                    raf.writeInt(zfie.offset);
+                    writtenSoFar += 4;
+
+                    // Write size of the file in the real Jar/Zip file
+                    raf.writeInt(zfie.size);
+                    writtenSoFar += 4;
+
+                    // Write compressed size of the file in the real Jar/Zip file
+                    raf.writeInt(zfie.compressedSize);
+                    writtenSoFar += 4;
+
+                    // Write java time stamp of the file in the real Jar/Zip file
+                    raf.writeLong(zfie.getLastModified());
+                    writtenSoFar += 8;
+                }
+            }
+        } catch (Throwable t) {
+            // Do nothing
+        } finally {
+            try {
+                if (raf != null) {
+                    raf.close();
+                }
+            } catch(IOException ioe) {
+                // Do nothing
+            }
+        }
+
+        return ret;
+    }
+
+    public boolean writeZipIndex() {
+        lock.lock();
+        try {
+            return writeIndex();
+        }
+        finally {
+            lock.unlock();
+        }
+    }
+
+    private File getIndexFile() {
+        if (zipIndexFile == null) {
+            if (zipFile == null) {
+                return null;
+            }
+
+            zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
+                    zipFile.getName() + ".index");
+        }
+
+        return zipIndexFile;
+    }
+
+    public File getZipFile() {
+        return zipFile;
+    }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndexEntry.java	Fri May 30 00:00:00 2008 +0200
+++ b/langtools/src/share/classes/com/sun/tools/javac/zip/ZipFileIndexEntry.java	Thu Jul 10 00:00:00 2008 +0200
@@ -1,91 +1,116 @@
-package com.sun.tools.javac.zip;
-
-import java.io.File;
-
-public final class ZipFileIndexEntry implements Comparable<ZipFileIndexEntry> {
-    public static final ZipFileIndexEntry[] EMPTY_ARRAY = {};
-    
-    // Directory related
-    String dir;
-    boolean isDir;
-    
-    // File related
-    String name;
-    
-    int offset;
-    int size;
-    int compressedSize;
-    long javatime;
-    
-    private int nativetime;
-    
-    public ZipFileIndexEntry(String path) {
-        int separator = path.lastIndexOf(File.separatorChar);
-        if (separator == -1) {
-            dir = "".intern();
-            name = path;
-        } else {
-            dir = path.substring(0, separator).intern();
-            name = path.substring(separator + 1);
-        }
-    }
-    
-    public ZipFileIndexEntry(String directory, String name) {
-        this.dir = directory.intern();
-        this.name = name;
-    }
-    
-    public String getName() {
-        if (dir == null || dir.length() == 0) {
-            return name;
-        }
-        
-        StringBuilder sb = new StringBuilder();
-        sb.append(dir);
-        sb.append(File.separatorChar);
-        sb.append(name);
-        return sb.toString();
-    }
-   
-    public String getFileName() {
-        return name;
-    }
-    
-    public long getLastModified() {
-        if (javatime == 0) {
-                javatime = dosToJavaTime(nativetime);
-        }
-        return javatime;
-    }
-
-    // From java.util.zip
-    private static long dosToJavaTime(int nativetime) {
-        // Bootstrap build problems prevent me from using the code directly
-        // Convert the raw/native time to a long for now
-        return (long)nativetime;
-    }
-    
-    void setNativeTime(int natTime) {
-        nativetime = natTime;
-    }
-    
-    public boolean isDirectory() {
-        return isDir;
-    }
-    
-    public int compareTo(ZipFileIndexEntry other) {
-        String otherD = other.dir;
-        if (dir != otherD) {
-            int c = dir.compareTo(otherD);
-            if (c != 0)
-                return c;
-        }
-        return name.compareTo(other.name);
-    }
-    
-    
-    public String toString() {
-        return isDir ? ("Dir:" + dir + " : " + name) :
-            (dir + ":" + name);
-    }
-}
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.tools.javac.zip;
+
+import java.io.File;
+
+public final class ZipFileIndexEntry implements Comparable<ZipFileIndexEntry> {
+    public static final ZipFileIndexEntry[] EMPTY_ARRAY = {};
+
+    // Directory related
+    String dir;
+    boolean isDir;
+
+    // File related
+    String name;
+
+    int offset;
+    int size;
+    int compressedSize;
+    long javatime;
+
+    private int nativetime;
+
+    public ZipFileIndexEntry(String path) {
+        int separator = path.lastIndexOf(File.separatorChar);
+        if (separator == -1) {
+            dir = "".intern();
+            name = path;
+        } else {
+            dir = path.substring(0, separator).intern();
+            name = path.substring(separator + 1);
+        }
+    }
+
+    public ZipFileIndexEntry(String directory, String name) {
+        this.dir = directory.intern();
+        this.name = name;
+    }
+
+    public String getName() {
+        if (dir == null || dir.length() == 0) {
+            return name;
+        }
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(dir);
+        sb.append(File.separatorChar);
+        sb.append(name);
+        return sb.toString();
+    }
+
+    public String getFileName() {
+        return name;
+    }
+
+    public long getLastModified() {
+        if (javatime == 0) {
+                javatime = dosToJavaTime(nativetime);
+        }
+        return javatime;
+    }
+
+    // From java.util.zip
+    private static long dosToJavaTime(int nativetime) {
+        // Bootstrap build problems prevent me from using the code directly
+        // Convert the raw/native time to a long for now
+        return (long)nativetime;
+    }
+
+    void setNativeTime(int natTime) {
+        nativetime = natTime;
+    }
+
+    public boolean isDirectory() {
+        return isDir;
+    }
+
+    public int compareTo(ZipFileIndexEntry other) {
+        String otherD = other.dir;
+        if (dir != otherD) {
+            int c = dir.compareTo(otherD);
+            if (c != 0)
+                return c;
+        }
+        return name.compareTo(other.name);
+    }
+
+
+    public String toString() {
+        return isDir ? ("Dir:" + dir + " : " + name) :
+            (dir + ":" + name);
+    }
+}